본문 바로가기
Java

Effective Java #08 equals를 재정의할 때는 일반 규약을 따르라

by NaHyungMin 2016. 4. 17.

equals 함수는 재정의하기 쉬워 보이지만 실수할 여지도 많고, 그 결과는 끔찍하다고 한다.

가장 간단한 방법은 equals 함수를 재정의 하지 않는 것인데 개인적으로 공통 함수로 제공되는 것들은 그냥 사용하는 것이

좋다고 생각한다. 꼭 필요할 경우에만 재정의 하도록 하자.


그렇다면 Object.equals를 재정의하는 것이 바람직할 때는 언제인가?

객체동일성(object equality)이 아닌 논리적 동일성(logical equality)의 개념을 지원하는 클래스일 때, 그리고 상위 클래스의 equals가 하위 클래스의 필요를

충족하지 못할 때 재정의해야 한다.


equals 함수를 정의할 때 준수해야 하는 일반 규약은 다음과 같다.(Object 클래스 명세에서 복사한 것이다.)

동치 관계(equivalence relation)를 구현한다. 다음과 같은 관계를 동치 관계라 한다.


반사성(reflexive) : null 아닌 참조 x가 있을 때 x,equals(x)는 true를 반환한다.

대칭성(symmetric) : null 아닌 참조 x와 y가 있을 때, x.equals(y)는 y.equals(x)가 true일 때만 true를 반환한다.(서로가 true여야 true 성립)

추이성(transitive) : null 아닌 참조 x,y,z가 있을 때 x.equals(y)가 true고 y.equals(z)가 true이면, x.equals(z)도 트루이다. x = y, y = z, x = z

일관성(consistent) : null 아닌 참조 x, y가 있을 때 equals를 통해 비교되는 정보에 아무 변화가 없다며느 x.equals(y) 호출 결과는 호출 횟수에 상관없이 같아야 한다.

null 아닌 참조 x에 대해서, x.equals(null)은 항상 false이다.


수학적 개념으로 생각하면 간단하다. 그렇게 어려운 개념이 아니기에 대칭 구조만 잘 이해하고 넘어가면 된다.


상황에 따라 코드는 다르기에 자세한 설명은 생략한다.

왠만하면 그냥 있는 함수 쓰는게 좋다고 배웠기에, 그대로 사용하도록 하고 정말 불가피할 경우 위에 조건을 충족 시키며 코드를 구현하길 바란다.