equals매서드는 아래의 상황중 하나에 해당되면 재정의하지 않는것이 최선이다.
- 각 인스턴스가 본질적으로 고유하다.
- 인스턴스의 ‘논리적 동치성(logical equality)'을 검사할 일이 없다.
- 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.
- ex) Set 구현체 AbstractSet이 구현한 equals 상속받아 사용, List 구현체는 AbstractList로부터 상속, Map 구현체는 AbstractMap로부터 상속
- 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없다.
실수로라도 equals 호출 되는것을 막는 방법
@Override public boolean equals(Object o){
throw new AssertionError();//호출 금지
}
equals를 재정의해야 할 때는 언제일까?
논리적 동치성을 확인해야하는데, 상위클래스의 equals가 논리적 동치성을 비교하도록 재정의하지 않았을때.
equals의 일반규약
- 반사성(reflexivity) : null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 true
- 자기 자신과 같아야 함
- 대칭성(symmetry) : null이 아닌 모든 참조 값 x,y에 대해, x.equals(y)가 true 이면 y.equals(x)도 true
- 두 객체는 서로에 대한 동치 여부에 똑같이 답해야 함
- 추이성(transitivity) : null이 아닌 모든 참조 값 x,y,z에 대해 x.equals(y)가 true 이고 y.eqauls(z)도 true 이면 x.eqauls(z)도 true
- 첫 번째 객체와 두 번쨰 객체가 같고, 두 번째 객체와 세 번째 객체가 같다면, 첫 번째 객체와 세 번쨰 객체도 같아야 함
- 일관성(consistency) : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)를 반복 호출하면 항상 true 이거나 false 를 반환
- 두 객체가 같다면 영원히 같아야 함
- null 아님 : null이 아닌 모든 참조 값 x에 대해, x.equals(null)은 false
- 모든 객체가 null과 같지 않아야 함
equals 단계별 구현 방법
- == 연사자를 사용해 입력이 자기 자신의 참조인지 확인한다.
- instanceof 연산자로 입력이 올바른 타입인지 확인한다.
- 입력을 올바른 타입으로 형변환 한다.
- 입력 객체와 자기 자신의 대응되는 ‘핵심’ 필드들이 모두 일치하는지 하나씩 검사한다.
전형적인 equals 메서드의 예
public final class PhoneNumber {
private final int areaCode, prefix, lineNum;
public PhoneNumber(int areaCode, int prefix, int lineNum) {
this.areaCode = areaCode;
this.prefix = prefix;
this.lineNum = lineNum;
}
@Override public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false;
PhoneNumber pn = (PhoneNumber)o;
return pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode;
}
}
equals 재정의 시 주의사항
- equals 재정의 시 hashCode도 반드시 재정의
- 너무 복잡하게 해결하려 하지 말자.
- 필드들의 동치성만 검사해도 됨
- Object 외의 타입을 매개변수로 받는 equals 메서드는 선언하지 말자.
'Effective java' 카테고리의 다른 글
[ITEM 13] clone재정의는 주의해서 진행하라 (0) | 2021.08.29 |
---|---|
[ITEM 12] toString을 항상 재정의하라 (0) | 2021.08.29 |
[ITEM9] try-finally보다는 try-with-resources를 사용하라 (0) | 2021.08.29 |
[ITEM 7] 다 쓴 객체 참조를 해제하라 (0) | 2021.08.29 |
[ITEM6] 불필요한 객체 생성을 피하라 (0) | 2021.08.28 |