Effective Java 2판 - 2, 3장 정리 (객체 생성, 공통 메서드)

0. 들어가며


면접 준비를 하면서 큰 도움을 주셨던 분께서 강력 추천해주셨던! 책인 Effective Java를 읽어보려고 합니다. 항상 그렇지만 읽기만 하는 것은 휘발성이 강하므로 글로 열심히 남겨서 정리할 예정입니다 :)

 

 

2장 객체의 생성과 삭제


규칙1: 생성자 대신 정적 팩토리 메소드를 사용할 수 없는지 생각해보라

정적 팩토리 메소드

장점

a)    생성자와는 달리 정적 팩토리 메소드에는 이름이 있다.

b)    생성자와는 달리 호출할 때마다 새로운 객체를 생성할 필요는 없다.

c)    생성자와는 달리 반환값 자료형의 하위 자료형 객체를 반환할 수 있다.

d)    형인자 자료형(parametized type) 객체를 만들 때 편하다. (kotlin과 연관성)

단점

a)    public이나 protected로 선언된 생성자가 없으므로 하위 클래스로 만들 수 없다.

b)    정적 팩토리 메소드가 다른 정적 메소드와 확연히 구분되지 않는다.

 

규칙2: 생성자 인자가 많을 때는 Builder 패턴 적용을 고려해라.

책에서 설명하는 단점은 빌더 객체를 생성해야 된다는 점인데 lombok으로 인해 희박한 것 같다. kotlin에서 선택적 인자에 이름을 붙일 수 있도록 허용한다는 점의 이유를 알거같다.

 

 

규칙 3: private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계해라.

 

규칙 4: 객체 생성을 막을 때는 private 생성자를 사용해라.

정적 메소드나 필드만 모은 클래스를 사용하고 싶을 때. 기본 자료형 값 또는 배열에 적용되는 메서드를 한 곳에 모아둘 때 유용하다. 이런 Utility 클래스들은 객체가 있는 것이 부자연스럽다. 따라서 생성자를 private으로 만들어 객체가 만들어지지 않도록 하자.

 

규칙 5: 불필요한 객체는 만들지 말라.

기능적으로 동일한 객체는 필요할 때마다 만드는 것보다 재사용하는 편이 낫다. 불변 객체는 특히 그렇고 변경 가능한 객체도 변경할 일이 없다면 재사용하는 것이 좋다. 성능 측면에서 특히.

 

규칙 6: 유효기간이 지난 객체 참조는 폐기하라.

실수로 객체 참조를 계속 유지하는 경우, 해당 객체만 GC에서 제외되는 것이 아니라 그 객체를 통해 참조되는 다른 객체들도 GC 대상에서 제외된다. Java에서 메모리 누수는 생소할 수 있지만 의도치 않은 객체 보유로 충분히 가능하다.

 

규칙 7: 종료자 사용을 피하라. 차라리 명시적인 종료 메서드를 하나 정의해라.

 

3: 모든 객체의 공통 메서드


Object는 기본적으로 계승해서 사용하도록 설계된 클래스이다. Object에 정의된 비-final method(equals, hashCode, toString, clone, finalize)가 대표적이다.

 

규칙 8: equals를 재정의는 값 클  래스처럼 논리적 동일성의 개념을 지원할 때 하자. 또한 동치 관계를 준수하자. (반사성, 대칭성, 추이성, 일관성, null과 비교는 false)

equals를 재정의하지 않으면 메모리 참조를 비교하기 때문에 모든 객체는 자기 자신과 같다. (객체 동일성)

논리적 동일성을 위해 equals를 재정의한다면 다음과 같은 절차를 따르자.

a)    == 연산자를 사용하여 equals의 인자가 자기 자신인지 검사하고 그렇다면 true를 반환해라.

b)    instanceof 연산자를 사용하여 인자의 자료형이 정확한지 검사하고 다르다면 false를 반환해라.

c)    equals의 인자를 정확한 자료형으로 변환해라.

d)    중요필드 각각이 인자로 주어진 객체의 해당 필드와 일치하는지 검사해라.

e)    대칭성, 추이성, 일관성의 세 속성이 만족되는지 검토하라.

f)     인자형을 Object에서 다른 것으로 바꾸지 마라.

 

규칙 9: equals를 재정의할 때는 hashCode도 재정의해라.

+ equals hashCode 모두 intelliJ alt+insert로 자동생성을 지원하는 것도 사실. 만들고 기준에 따라 검토하면 될 것이다.

 

규칙 10: toString은 항상 재정의하라.

클래스를 쾌적하게 쓰기 위함이다. 실질적인 API 구실을 하게 된다.

 

규칙 11: clone을 재정의할 때는 신중해라.

객체를 복사할 대안을 제공하거나 아예 복제 기능을 제공하지 않는 것이 낫다. 객체 복제를 지원하는 좋은 방법은 복사 생성자나 복사 팩토리를 제공하는 것이다.

 

규칙 12: Comparable 구현을 고려하라.

equals와 마찬가지로 동치성 검사를 통과하도록 하자.