이펙티브 자바
-
Item 13. clone 재정의는 주의해서 진행하라백수의 개발/이펙티브 자바 2019. 8. 27. 20:32
Cloneable 인터페이스 Cloneable은 복제해도 되는 클래스임을 명시하는 용도의 믹스인 인터페이스(mixin interface)이다. 그러나 clone 메서드가 Cloneable이 아닌 Object에 protected로 명시되어 있다. 그래서 Cloneable을 구현한다고 해서 clone을 호출할 수 없다. 그럼에도 불구하고 Cloneable 방식은 널리 사용되고 있어 올바르게 사용하는 방법을 알아보자. Cloneable의 역할 메서드 하나 없는 Cloneable 인터페이스는 Object의 protected 메서드인 clone의 동작 방식을 결정한다. Cloneable을 구현한 클래스의 인스턴스에서 clone을 호출하면 그 객체의 필드들을 모두 복사한 객체를 반환하며, 그렇지 않은 클래스의 인스..
-
Item 12. toString을 항상 재정의하라백수의 개발/이펙티브 자바 2019. 8. 22. 17:38
Object의 기본 toString 메서드는 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없다. 일반적으로 TestClass@a7cd(클래스이름@16진수로 표시된 해시코드)와 같이 보여줄 뿐이다. 그래서 toString을 재정의하여 사람이 읽기 쉬운 형태의 유익한 정보를 반환할 필요가 있다. toString를 재정의하는 이유 전화번호를 저장하는 PhoneNumber객체가 있을 때, 이를 출력한다고 가정해보자. PhoneNumber Jeny = new PhoneNumber(707, 867, 5309); System.out.println("Jeny PhoneNumber : " + Jeny); 이와 같이 했을 때, 'Jeny PhoneNumber : PhoneNumber@abcd'와 'Jeny..
-
Item 11. equals를 재정의하려거든 hashCode도 재정의하라백수의 개발/이펙티브 자바 2019. 8. 20. 17:43
equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다. 이는 HashMap이나 HashSet같은 컬렉션의 원소로 사용할 때 문제를 일으킬 수 있기 때문이다. hashCode의 규약 equals에 비교되는 정보가 변경되지 않았다면, hashCode 메서드는 일관되게 항상 같은 값을 반환해야 한다.(단, 애플리케이션 재실행 시 값이 달라져도 상관없다.) equals가 두 객체를 같다고 판단했다면, 두 객체의 hashCode도 동일해야 한다. equals가 두 객체를 다르다고 판단하더라도, 두 객체의 hashCode가 다른 값을 반환할 필요는 없다.(단, 다른 값을 반환해주어야 해시테이블의 성능이 향상된다.) hashCode 재정의가 안되거나, 잘 못된 경우 대부분 hashCode 재정의 ..
-
Item 10. equals는 일반 규약을 지켜 재정의하라백수의 개발/이펙티브 자바 2019. 8. 13. 17:51
equals 메서드는 객체 내의 정보들에 대한 동등성을 비교하기 위한 메서드이다. 비교 가능한 객체의 경우 equals 메서드를 잘못 작성하게 되면 의도하지 않은 결과가 초래되니, equals를 재정의하는 방법에 대해 알아보자. equals를 재정의하지 않아도 되는 경우 1. 각 인스턴스가 본질적으로 고유하다. 데이터나, 객체의 정보를 표현하는 것이 아닌, 동작하는 개체를 표현하는 클래스가 이에 속한다.ex) Thread 2. 인스턴스의 '논리적 동치성'을 검사할 일이 없다. java.util.regex.Pattern은 Pattern의 인스턴스가 같은(동치성) 정규표현식을 나타내는지 검사할 필요가 없다. 3. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 대부분의 Set 구현체들..
-
Item 9. try-finally보다는 try-with-resource를 사용하라백수의 개발/이펙티브 자바 2019. 8. 9. 19:12
자바 라이브러리에는 InputStream, OutputStream, java.sql.Connection등 close메서드를 호출해 직접 닫아줘야 하는 자원이 많다. 이러한 자원을 닫기 위한 수단으로 try-finally가 사용되었다. try-finally는 더 이상 자원을 회수하는 최선의 방책이 아니다! 아래와 같은 try-finally를 통해 자원을 닫을 수 있다. static String firstLineOfFile(String path) throws IOException{ BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } 그러나 자원을 하나..
-
Item 8. finalizer와 cleaner 사용을 피하라백수의 개발/이펙티브 자바 2019. 8. 7. 16:34
finalizer와 cleaner를 피해야하는 이유 자바는 finalizer와 cleaner 두 가지 객체 소멸자를 제공한다. finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. cleaner는 finalizer보다는 덜 위험하지만, 여전히 예측할 수 없고, 느리고, 일반적으로는 불필요하다. 1. 실행을 보장할 수 없다. 위 두 가지 객체 소멸자로는 즉시 수행된다는 보장이 없다. 객체에 접근할 수 없게 된 후 finalizer나 cleaner가 실행되기까지 얼마나 걸릴지 알 수 없다. 즉, 이 두 가지 객체 소멸자로는 제때 실행되어야 하는 작업은 절대 할 수 없다. 상태를 영구적으로 수정하는 적업에는 절대 finalizer나 cleaner에 의존해서는 안 된다. 2...
-
Item 7. 다 쓴 객체 참조를 해제하라백수의 개발/이펙티브 자바 2019. 7. 19. 14:45
C, C++처럼 메모리를 직접 관리해야 하는 언어와 달리 Java는 가비지 컬렉터(GC)를 갖추어 어느정도 알아서 메모리를 관리해준다. 그러나 메모리 관리에 아예 신경 쓰지 않아도 된다는 것은 아니다. 크게 메모리 누수에 문제를 발생시키는 것들이 3가지 있다. 어떤 상황에서 메모리 관리를 신경써줘야할지 알아보자. 자기 메모리를 직접 관리하는 클래스 아래 Stack을 구현한 코드에서 메모리 누수가 일어나는 위치가 어디인지 확인해보자. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = ..
-
Item 6. 불필요한 객체 생성을 피하라백수의 개발/이펙티브 자바 2019. 7. 16. 14:58
자주 사용되는 객체의 재사용 자주 사용되는 객체가 있다면 이는 매번 생성하기보다는 객체 하나를 재사용하는것이 훨씬 빠르고 효율적이다. 우리가 많이 사용하는 Boolean객체를 사용할 때, 아래와 같이 작성한다면 Boolean객체는 항상 새롭게 생성될 것이다. Boolean trueObject = new Boolean(true); Boolean falseObject = new Boolean(false); 그래서 Boolean에서의 true와 false는 Boolean객체 내에서 정적 필드 변수로 가지고 있어 재활용 된다. 따라서 아래처럼 사용하면 별도의 객체를 생성하지 않고, 기존에 만들어진 객체를 그대로 재활용 할 수 있다. Boolean trueObject = Boolean.TRUE; Boolean f..