상속 대신 컴포지션을 사용하여 equals 구현을 우회하라고 했는데 어떻게 하는 것일까?
컴포지션은 먼저, 클래스 내부에 다른 클래스의 인스턴스를 멤버 변수로 선언한다. 그리고 equals() 메서드를 오버라이드하여, 멤버 변수의 equals() 메서드를 호출하도록 구현한다. 이렇게 함으로써 상속 대신 컴포지션을 이용하여 equals() 메서드를 구현할 수 있다.
또, 추상 클래스를 사용하여 상위 클래스를 인스턴스로 만들 수 없도록 하여 해결할 수도 있다.
일관성은 equals 판단에서 신뢰성이 보장되지 않는 값을 사용하지 않도록 하여 보장해야 한다
정리하자면 equals는
==을 사용해 참조 값이 같은지 확인 -> 단순 성능 최적화
instanceof 연산자로 올바른 타입인지 확인 -> null 에 대한 묵시적 처리, 형변환을 위함
넘어온 값을 올바른 타입으로 형변환
넘어온 값의 핵심 필드와 자기 자신의 핵심 필드가 모두 일치하는지 검사
참고.
null도 true로 처리할 필요가 있다면 Object.equals(o1, o2) 를 사용하자.
기본 타입은 == 으로, 참조 타입은 equals 로 값이 같은지 확인하자. (float, double 의 경우 Float.compare, Double.compare 를 활용하자. NaN, 부동 소수점 에러)
비교가 복잡하다면 해당 클래스의 표준형을 만들어 비교에 사용하자.
다를 가능성이 높은 필드부터 비교하자.