equals는 일반 규약을 지켜 재정의하라
재정의하지 않아도 되는 경우
- 각 인스턴스가 본질적으로 고유하다. ex) Thread
- 인스턴스의 논리적 동치성을 검사할 일이 없다.
- 상위 클래스에서 재 정의한 eqauls가 하위 클래스에도 딱 맞는다.
- 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없다.
재정의해야 할 때
- 논리적 동치성을 확인해야 하는데, 상위 클래스의 equals가 논리적 동치성을 비교하도록 재정의되지 않았을 때. ex) String, Integer (값 클래스)
- 5가지 규약을 지켜야 한다. (반사성, 대칭성, 추이성, 일관성, null-아님)
equals를 재정의하려거든 hashCode도 재정의하라
- equals가 두 객체를 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환해야 한다. (논리적으로 같은 객체는 같은 hashCode를 반환해야 한다.)
- 성능을 위해 hashCode를 계산할 때 핵심 필드를 생략해서는 안 된다.
- hashCode가 반환하는 값의 생성 규칙을 API사용자에게 자세히 공표하지 말자. (클라이언트가 이 값에 의지하지 않게 되고, 추후에 계산 방식을 바꿀 수도 있다.)
toString을 항상 재정하라
- toString은 그 객체가 가진 주요 정보 모두를 반환하는 게 좋다.
- 포맷을 명시하든 아니든 의도를 명확히 밝혀야 한다.
- toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하자.
clone 재정의는 주의해서 진행하라
- Cloneable을 구현한 클래스는 cline 메서드를 public으로 제공하며, 사용자는 당연히 복제가 제대로 이뤄지리라 기대한다.
- clone 메서드는 사실상 생성자와 같은 효과를 낸다. 즉, clone은 원본 객체에 아무런 해를 끼치지 않는 동시에 복제된 객체의 불변식을 보장해야 한다.
- Cloneable 아키텍처는 '가변 객체를 참조하는 필드는 final로 선언하라'는 일반 용법과 충돌한다. (복제할 수 있는 클래스를 만들기 위해 일부 필드에서 final 한정자를 제거해야 할 수도 있다.)
- Cloneable을 이미 구현한 클래스를 확장한다면 어쩔 수 없이 clone을 잘 작동하도록 구현해야 하지만, 그렇지 않은 상황에서는 복사 생성자와 복사 팩토리를 사용하는 더 나은 객체 복사 방식을 제공할 수 있다.
Comparable을 구현할지 고려하라
- Comparable의 유일한 메서드는 int compareTo(T t).
- compareTo의 일반 규약은 equals와 비슷하다.
- compareTo 메서드에서 관계 연산자 <(<) 와 >(>) 사용은 추천하지 않고, 박싱된 기본 타입 클래스들에 새로 추가된 정적 메서드인 compare나 Comparator 인터페이스가 제공하는 비교자 생성 메서드를 사용하자.
'책 > Effective Java' 카테고리의 다른 글
람다와 스트림 (0) | 2020.03.20 |
---|---|
열거 타입과 애너테이션 (0) | 2020.03.18 |
제네릭 (0) | 2020.03.17 |
클래스와 인터페이스 (0) | 2020.03.14 |
객체 생성과 파괴 (0) | 2020.03.10 |