아이템 10 - equals는 일반 규약을 지켜 재정의하라
JAVA
·
equals는 재정의 하지 않는 것이 최선이다.
- 다음의 경우에 해당한다면 equals를 재정의 할 필요가 없다.
- 각 인스턴스가 본질적으로 고유한 경우
- 값을 표현하는 게 아니라 동작하는 개체를 표현하는 경우
- 인스턴스의 ‘논리적 동치성’을 검사할 필요가 없는 경우
- 상위 클래스에서 재정의한 equals가 하위 클래스에도 적절한 경우
- 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없는 경우
- 실수로 호출하는 걸 막고 싶다면 AssertionError을 던지게 재정의해라.
</br>
</br>
equals를 재정의해야 하는 경우
- 객체 식별성이 아니라 논리적 동치성을 확인해야 하는데, 상위 클래스의 equals가 논리적 동치성을 비교하도록 재정의되지 않은 경우
- 주로 값 클래스(Integer, String처럼 값을 표현하는 클래스)들이 여기 해당
- 두 값 객체를 비교하는 프로그래머는 객체가 같은지가 아니라 값이 같은지를 알고 싶어할 것이다.
- 값 클래스라도 값이 같은 인스턴스가 둘 이상이 만들어지지 않음을 보장한다면 equals를 재정의하지 않아도 된다.
</br>
</br>
equals 규약
- 반사성 : A.equals(A) == true
- 대칭성 : A.equals(B) == B.equals(A)
- 추이성 : A.equals(B) && B.equals(C) == A.equals(C)
- 일관성 : A.equals(B) == A.equals(B)
- null-아님 : A.equals(null) == false
</br>
</br>
equals 구현 방법
- == 연산자를 사용해 자기 자신의 참조인지 확인한다.
- instanceof 연산자로 올바른 타입인지 확인한다.
- 입력된 값을 올바른 타입으로 형변환 한다.
- instanceof 검사를 했기에 무조건 성공하는 단계
- 입력 객체와 자기 자신의 대응되는 핵심 필드가 일치하는지 확인한다.
- 구글의 AutoValue 또는 Lombok 또는 IDE 코드 자동 생성을 사용한다.
</br>
</br>
주의사항
- equals를 재정의 할 때 hashCode도 반드시 재정의하자.
- 너무 복잡하게 해결하지 말자.
- 필드들의 동치성만 검사해도 equals 규약을 어렵지 않게 지킬 수 있다.
- 너무 파고들다가 오히려 문제를 일으킬 수 있다.
- Object가 아닌 타입의 매개변수를 받는 equals 메서드는 선언하지 말자.
- 재정의한 게 아닌 새로운 메서드를 정의한 꼴이 될 수 있다.
</br>
</br>
출처
이펙티브 자바 3/E
이펙티브 자바 완벽 공략 1