Object 는 모든 객체 생성이 가능한 클래스이긴 하지만 기본적으로 계승해서 사용하도록 설계된 클래스 이다.
그런 Object에 정의된 equals, hashCode, toString, clone, finalize는 명시적인 일반 규약이 있다.
재정의 하도록 설계된 메서드들이기 때문에 상황에 따라 재정의를 하지 않을 경우 HashMap, HashSet처럼
해당 규약에 의존하는 클래스와 함께 사용하면 문제가 발생한다.
※ equals를 재 정의 하지 않아도 되는 경우
이중 equals 메서드에 대해서 이야기 해보자.
Equals 재정의를 하였을 때 실패할 경우, 문제가 되기 때문에 아래와 같은 상황에서는 구태여 재정의 하지 않아도 된다.
1. 각각의 객체가 고유하다.
- Thread 같은 클래스는 Object의 equals 메소드를 그대로 사용해도 된다.
2. 구태여 equals 메소드를 사용할 필요가 없을 경우
3. 상위 클래스에서 정의한 equals를 그대로 승계하여 사용하여도 무방한 경우
4. 클래스가 private, package-private로 선언되어 있는경우, equals 메소드를 정의할 필요가 없다.
※ equals 재정의 시 준수해야 하는 일반 규약
- null이 아닌 참조 x가 있을 때, x.equals(x)는 true를 반환한다.
- null이 아닌 참조 x, y가 있을 때, x.equals(x), y.equals(x)가 true일 때 true 반환
- null이 아닌 참조 x, y, z가 있을 때, x.equals(y)가 true이고, y.equals(z)가 true이면 x.equals(z)도 true이다.
- null이 아닌 참조 x에 대해서, x.equals(null)은 항상 false이다.
※ 좋은 equals 재정의 시 준수해야 하는 일반 규약
1. == 연산자를 사용하여 eqauals의 인자가 본인과 같은지 확인하자
- 그렇게 true를 반환하면 훨씬 더 속도가 빠르다.
2. instanceof 연산자를 통하여 인자의 자료형이 같은지 확인하라.
3. equals에 사용될 인자를 정확한 자료형으로 캐스팅하라
- instanceof 연산자를 통해 정확하게 점검하였다면 캐스팅에 문제가 없을 것이다.
4. 자료형에 맞게 비교하라.
- float, double 이외의 기본 자료형은 == 연산자로 비교하고, float는 Float.compare 메서드를 double 필드는 Double.compare 메소드를 이용하여 비교하라. (float와 double필드는 Float.NaN, -0.0f와 같은 상수가 있기 때문이다.)
5. NULL이 허용되는 필드를 비교해야 할 때 NULL 포인트 에러를 피하라.
- (field == o.field || ( field != null & field.equlas(o.field)))
6. 성능을 최대한 끌어내기 위해서 다를 가능성이 가장 높거나 비교 비용이 낮은 필드부터 먼저 비교 한다.
출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙8 인용
'JAVA > Effective Java' 카테고리의 다른 글
모든 객체의 공통 메서드 - 규칙 10 toString은 항상 재정의하라 (0) | 2018.05.29 |
---|---|
모든 객체의 공통 메서드 - 규칙 9 equals를 재정의할 때는 반드시 hashCode도 재정의하라 (0) | 2018.05.29 |
객체의 생성과 삭제 - 규칙 7 종료자 사용을 피하라 (0) | 2018.05.29 |
객체의 생성과 삭제 - 규칙 6 유효기간이 지난 객체 참조는 페기하라. (0) | 2018.05.29 |
객체의 생성과 삭제 - 규칙 5 불필요한 객체는 만들지 말라 (0) | 2018.05.29 |