Effect Java 제2판(Joshua Bloch / Addison Wesley) 을 공부하고 정리한 내용 입니다.
8. equals 메소드를 오버라이딩 할 때는 보편적 계약을 따르자.
다음 조건 중 어느 하나라도 만족하면 equals 오버라이드를 하지 않고 상속 받은 그대로 사용하자.
- 클래스의 각 인스턴스가 본래부터 유일한 경우.
- 두 인스턴스가 논리적으로 같은지 검사하지 않아도 되는 클래스의 경우
- 수퍼 클래스에서 equals 메소드를 이미 오버라이딩 했고, 그 메소드를 그대로 사용해도 좋은 경우
- private이나 패키지 전용(package-private) 클래스라서 이 클래스의 equals 메소드가 절대 호출되지 않아야 할 경우
객체 참조만으로 인스턴스의 동일 여부를 판단하는 것이 아니라, 인스턴스가 갖는 값을 비교하여 논리적으로 같은지 판단할 필요가 있는 클래스로써, 자신의 수퍼클래스에서 equals 메소드를 오버라이드 하지 않았을 때 Object.equals 를 오버라이드 하는 것이 좋다.
equals 메소드를 오버라이드 할 때는 이 메소드의 보편적 계약을 따라야 한다.
equals 메소드는 동등 관계(equivalence relation)을 구현하며, 그것은
- 재귀적이다(Reflexive) : null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 반드시 true를 반환해야 한다.
- 대칭적이다(Symmetric) : null이 아닌 모든 참조 값 x와 y에 대해, y.equals(x)가 true를 반환한다면 x.equals(y)도 반드시 true를 반환해야 한다.
- 이행적이다(Transitive) : null이 아닌 모든 참조 값 x, y, z에 대해, 만일 x.equals(y)가 true를 반환하고 y.equals(z)가 true를 반환한다면 x.equals(z)도 반드시 true를 반환해야 한다.
- 일괄적이다(Consistent) : null이 아닌 모든 참조 값 x와 y에 대해, equals 메소드에서 객체 비교 시 사용하는 정보가 변경되지 않는다면, x.equals(y)를 여러 번 호출하더라도 일관성 있게 true 또는 false를 반환해야 한다.
- null이 아닌 모든 참조 값 x에 대해, x.equals(null)은 반드시 false를 반환해야 한다.
좋은 equals 메소드를 만드는 방법은 다음과 같다.
- 객체의 값을 비교할 필요 없고 참조만으로 같은 객체인지 비교 가능하다면 == 연산자를 사용하자.
- instanceof 연산자를 사용해서 전달된 인자가 올바른 타입인지 확인하자.
- 인자 타입을 올바른 타입으로 변환한다.
- 클래스의 중요한(꼭 비교해야 하는) 필드 각각에 대해서는 인자로 전달된 객체의 필드와 현재 객체(equals) 메소드가 호출된)의 필드가 모두 같은지 빠뜨리지 말고 비교한다.
- 우리의 equals 메소드를 작성한 후에는 보편적 계약을 따르는지 확인하고 단위 테스트 코드를 작성하여 그런 속성들이 지켜지는지 검사한다.
유의 사항
- equals 메소드를 오버라이드 할 때는 hashCode 메소드도 항상 오버라이드 한다.
- 너무 똑똑한 척 하지마라. 단순히 필드 값이 같은지 검사하는 것이라면 equals 계약 준수가 어렵지 않다. 하지만 너무 지나치게 동일 여부를 비교하려 하면 문제가 생기기 쉽다.
- equals 메소드의 인자 타입을 Object 대신 다른 타입으로 바꾸지 말자.
'Programs > Java' 카테고리의 다른 글
모든 객체에 공통적인 메소드 - 10. toString 메소드는 항상 오버라이드 하자. (1) | 2012.11.05 |
---|---|
모든 객체에 공통적인 메소드 - 9. equals 메소드를 오버라이드 할 때는 hashCode 메소드도 항상 같이 오버라이드 하자. (1) | 2012.11.05 |
객체의 생성과 소멸 - 7. 파이널라이저(finalizer)의 사용을 피하자 (1) | 2012.11.01 |
객체의 생성과 소멸 - 6. 쓸모 없는 객체 참조를 제거하자. (0) | 2012.11.01 |
객체의 생성과 소멸 - 5. 불필요한 객체의 생성을 피하자. (2) | 2012.10.30 |