* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 12. Comparable 구현을 고려하라 두 객체를 비교하는데 사용되는 compareTo 메서드는 Object에 선언되어 있지 않다. Comparable 인터페이스에 선언되어있는 유일한 메서드이다. - Object의 equals 메서드와 특성은 비슷하지만, 단순 동치성 비교(== 비교, 동등성)에 더해 순서 비교가 가능하며 조금 더 일반적인 형태(제네릭 하다). public interface Comparable { public int compareTo(T o); } Comparable 인터페이스를 구현하는 클래스의 객체들은 자연적 순서(Natural Ordering)을 갖게 된다. 덕분에 검색하거나 최대/최소값을 계산하기도 간단하며, ..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 11. clone을 재정의할 때는 신중하라 Clonable 인터페이스는 어떤 객체가 복제(clone)을 허용한다는 사실을 알리기 위해 만들어진 믹스인(mixin) 인터페이스. public interface Cloneable { } 실제로 Cloneable 인터페이스를 보면 아무 내용도 없다는 것을 확인할 수 있다. - Object 클래스 내 protected clone() 메서드가 어떻게 동작할 지 규정하는 용도로 사용되어진다. 어떤 클래스가 Cloneable을 구현한다면, clone 메서드는 해당 객체를 필드 단위로 복사한 객체를 반환한다. Cloneable 구현을 하지 않았다면 clone 메서드 사용 시 CloneNotSupporte..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 10. toString은 항상 재정의하라 잘 만들어놓은 toString은 클래스를 좀 더 쾌적하게 사용할 수 있도록 도움을 준다. - 가능하면 toString 메서드는 객체 내의 중요 정보를 전부 담아 반환해줘야 한다. toString을 따로 재정의하지 않으면 Object에 정의된 toString 메서드가 사용되는데 이는.. public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } - 클래스 이름@16진수 해시코드가 출력되게 된다. 썩 마음에 들지가 않는다 - 모든 하위 클래스는 이 메서드를 재정의함이 바람직하다. 사람이..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 9. equals를 재정의할 때는 "반드시" hashCode도 재정의하라 equals 메서드를 재정의(오버라이딩)하는 클래스는 "반드시" hashCode 메서드도 재정의 해야한다. 그렇지 않으면 Object.hashCode의 일반 규약을 어기게 되어 HashMap, HashSet, HashTable과 같은 해시 기반 컬렉션과 함께 사용할 시 문제가 발생한다 Object.hashCode 클래스의 일반 규약이 뭐길래 그럴까? 1. 응용프로그램 실행 중 같은 객체의 hashCode를 여러번 호출하는 경우, equals가 사용하는 정보들이 변경되지 않았다면 언제나 동일한 값이 반환되어야 한다. 당연한 이야기. (단 프로그램이 재시작 된 경우에는..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 모든 자바 클래스의 최고 조상 클래스인 Object 클래스는 객체 생성이 가능한 클래스지만, 기본적으로는 계승해서 사용하도록 만들어진 클래스이다. - Object에 정의된 비-final(final이 아닌) 메서드: equals, hashCode, toString, clone 등.. -> 명시적인 일반 규약이 존재하고, 오버라이드 해서 사용하도록 설계된 메서드들이다. 위 메서드를 재정의하는 클래스는 해당 일반 규약을 따라야 한다. 8. equals를 재정의할 때는 일반 규약을 따르라. equals 메서드는 언제 재정의 해서 사용해야 하는가? 1. 객체 동일성(Object equality)가 아닌, 논리적 동일성(Logical equalit..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 7. 종료자 사용을 피하라 종료자(finalizer)는 예측 불가능하고, 대체로 위험하고, 일반적으로 불필요하다. 근데 잠깐.. 종료자가 뭐지? 한번도 들어보지를 못했다. GC 수행을 요청하는 메서드와 관련이 있는 것 같은데.. (System.gc(), System.runFinalization() 등..) 그런데 Finalizer는 자바 9에서는 Deprecated된 개념으로, Cleaner 라는 개념으로 대체되었다고 한다. 어차피 쓰지 않을 것이었다! 그래서 그냥 자원을 해제할 때에는 try-with-resources 구문을 사용하는 것이 깔끔쓰하다. 그러니 try-with-resources 문에 대해서나 알아보자 try-catch-f..
* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다. 6. 유효기간이 지난 객체 참조는 폐기하라 자체적으로 관리하는 메모리가 있는 클래스를 만들 때에는 메모리 누수가 생기지 않도록 신경써야 한다. - 사용되지 않는 객체가 처리되지 않고 메모리 상에 계속 남아있으면, 그것이 쌓이고 쌓이다가 나중에 가서 문제를 일으키게 된다. -> 만기 참조(Obsolete reference)가 GC에 의해 처리되지 않고 계속 남아있기 때문. * 만기 참조: 더이상 이용되지 않을 참조(주소값) -> 더이상 사용되지 않는 객체가 사라지지 않고 계속 힙 영역에 잔류 -> 이를 "의도치 않은 객체 보유(Unintentional object retention)" 이라고 한다. 이 만기 참조 객체는, 해당 객체가 참조..
5. 불필요한 객체는 만들지 말라 1) 기능적으로 동일한 객체는 필요할 때마다 만드는 것보다 재사용하는 것이 더 낫다. - 변경 불가능한(immutable) 객체는 언제든지 재사용할 수 있다. - 변경 불가능한 클래스(final class. 대표적으로 String, Math 등...) 의 경우, 생성자보다는 정적 팩토리 메서드를 이용하면 불필요한 객체 생성을 막을 수 있다. 메서드를 호출할 때마다 생성되는 객체가 많아 비용이 높다면 정적 초기화 블록(Static initializer)를 사용해보자 =============== * 필드를 초기화 하는데에는 3가지 방법이 있다 1. 명시적 초기화 (= 선언과 동시에 초기화하는 것) 2. 생성자 초기화 3. 초기화 블록을 통한 초기화 초기화 블록은 또 다시 인..