equals 메소드를 오버라이딩 할 때는 보편적 계약을 따르자
- 클래스의 각 인스턴스가 본래부터 유일한 경우
- 두 인스턴스가 논리적으로 같은지 검사하지 않아도 되는 경우
- 수퍼 클래스의 equals를 오버라이딩했고, 이를 그대로 사용해도 무방한 경우
- equals를 호출하면 안되는 경우
위와 같은 경우 equals를 오버라이딩 하자.
equals()
는 동등관계 구현
- 재귀적:
x.equals(x)
는 true - 대칭적:
x.equals(y)
가 true 라면,y.equals(x)
도 true - 이행적:
x.equals(y)
가 true고x.equals(z)
도 true 라면,y.equals(z)
는 true - 일관적: 정보가 변경되지 않았다면, 여러 호출하더라도 일관된 값을 반환해야 한다.
x.equals(null)
는 false
</br>
- equals 계약을 어기면, 객체들이 어떻게 동작할지 알 수 없다.
- ‘상속보다는 컴포지션을 이용하자’가 동등성의 어려움에서 벗어나는 차선책이 될 수 있다.
equals()
에서의 null 검사는 불필요하다.
정리
- 객체의 값을 비교할 필요 없고 참조만으로 같은 객체인지 비교 가능하다면
==
를 사용하자. instanceof
를 사용해서 전달된 인자가 올바른 타입인지 확인하자.- 인자 타입을 올바른 타입으로 변환한다.
- 필드 각각에 대해서는 인자로 전달된 객체의 필드와 현재 객체
(equals 메소드가 호출된)의 필드가 모두 같은지 빠뜨리지 말고 비교한다.
Double
과Float
는compare()
를 사용하자.
equals()
를 작성한 후에는 과연 그 메소드가 대칭적이며 이행적이고 일관성이 있는지 확인한다.
유의사항
equals()
를 오버라이드 할 때는hashCode()
도항상 오버라이드 한다.- 너무 지나치게 통일 여부를 비교하려 하변 문제가 생기기 쉽다.
equals()
의 인자 타입을 Object 대신 다른 타입으로 바꾸지 말자.
참고
- https://projectlombok.org/features/EqualsAndHashCode