티스토리 뷰
Item 10. equals는 일반 규약을 지켜 재정의하라
Jordy-torvalds 2019. 12. 8. 18:50equals 재정의시 주의사항
equal 메서드는 재정의 하기 쉬워 보이지만 자칫하면 끔직한 결과를 초래한다. 아래 케이스에 해당하면 재정의를 하지말자.
각 인스턴스가 본질적으로 고유하다.
값을 표현하는게 아니라 동작하는 개체를 표현하는 클래스가 여기 해당한다.인스턴스의 논리적 동치성(Logical Equality)을 검사할 일이 없다.
java.util.regex.Pattern이란 정규식을 담는 클래스를 재정의해서 두 패턴의 인스턴스가 같은 정규표현식을 나타내는지 논리적 동치성을 검사하는 방법도 있지만, 설계자가 원하지 않거나 불필요할 수 있다. 후자의 경우에는 Object의 기본 equals로 충분하다.상위클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.
예컨데 Set구현체는 AbstractSet이 구현한 equals를 상속받아 쓰고, List구현체는 AbstractList로 부터 상속받아 그대로 쓴다.클래스가 private이거나 package-private(default)이고 equals메서드를 호출할 일이 없다.
위험을 철저히 회피하는 스타일이여서 equals 가 실수로라도 호출되는 것을 막고 싶으면 아래와 같이 구현해두자.@Override
public boolean equals(Object o){throw new AsserstionError(); // 호출금지
}
equals를 재정의 해야할 때
객체 식별성(object identity, 두 객체가 물리적으로 같은가)이 아니라 논리적 동치성을 확인해야 하는데, 상위 클래스의 equals가 논리적 동치성을 비교하도록 재정의되지 않았을 때다. 주로 값 클래스(Integer, String 등 값 표현 클래스)가 여기에 해당한다.
물론 값 클래스라도 Item 1에 소개된 정적 팩토리 클래스과 Enum이라면 equals를 정의 하지 않아도 된다.
equals 메서드 재정의 규약
equals 메서드는 동치관계(equivalence relation)을 구현하며, 다음을 만족한다.
- 반사성(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.equals(z)도 true면 x.equals(z)도 true다.
- 일관성(consistency): null이 아닌 모든 참조 값 x, y에 대해, x.equals(y)를 반복해서 호출하면 항상 true를 반환하거나 항상 false를 반환한다.
- null-아님: null이 아닌 모든 참조 값 x에 대해, x.equals(null)은 false다.
equals 메서드 단계별 구현 방법.
- == 연산자를 사용해 입력이 자기 자신의 참조인지 확인한다.
- instanceof 연산자로 입력이 올바른 타입인지 확인한다.
- 입력을 올바른 타입으로 형변환한다.
- 입력객체와 자기 자신의 대응되는 핵심 필드들이 모두 일치하는 지 하나 씩 검사한다.
equals 메서드 구현간 주의사항
- equals를 재정의할 땐 hashcode도 반드시 재정의하자.(아이템 11).
- 너무 복잡하게 해결하려 들지마자.
필드들의 동치성만 검사해도 equals 규약을 어렵지 않게 지킬 수 있다. - Object 외의 타입을 매개변수로 받는 equals 메서드는 선언하지 말자.
정리.
- 꼭 필요한 경우가 아니면 equals를 재정의하지 말것. 구현한다면 다섯가지 규약을 확실히 지켜가며 핵심 필드들을 비교해야한다.
'Essential Language Skill > Effective Java' 카테고리의 다른 글
Item 12. toString을 항상 재정의하라 (0) | 2019.12.11 |
---|---|
Item 11. equals를 재정의하려거든 hashcode도 재정의하라 (0) | 2019.12.08 |
Item 9. try-finally보다는 try-with-resource를 사용하라 (0) | 2019.12.08 |
Item 7. 다 쓴 객체 참조를 해제하라 (0) | 2019.12.08 |
Item 6. 불필요한 객체 생성을 피하라 (0) | 2019.12.08 |
- Total
- Today
- Yesterday
- Java Memory Structure
- JVM
- Delete
- kubernetes
- Replication Controller
- POD
- Java
- Effective Java
- 자바 메모리 구조
- k8s
- JMM
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |