윤개발

[ITEM10] equals는 일반 규약을 지켜 재정의하라. 본문

책 내용 요약/Effective Java 3판

[ITEM10] equals는 일반 규약을 지켜 재정의하라.

DEV_SJ 2020. 4. 14. 13:33

재정의를 하지 않는다.

equals 메서드는 재정의하기 쉬워보이지만 곳곳에 함정이 있어 큰 문제가 될 수 있다.
가장 쉬운 길은 아예 재정의를 하지 않는 것이다. 아래 상황에 해당한다면 재정의 하지 않는것이 최선이다.

  1. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는게 아니라 개체를 표현하는 클래스가 해당된다.
  2. 인스턴스의 논리적 동치성을 검사할 일이 없다.
  3. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.
  4. 클래스가 private 여서 equals를 호출할 일이 없다.

실수로라도 호출되는 걸 막고싶다면 예외처리로 throw new AssertionError()를 발생시키자..


재정의 하는 상황

  • 논리적 동치성을 비교해야할 때 재정의하면 좋다. 객체가 아니라 값이 같은지를 알고싶을때
  • Map의 키, Set의 원소 등으로 사용할 때

재정의 할 때는 다음 일반 규약을 따라야 한다.

  1. 반사성 : 객체 X에 대하여 x.equals(x)는 true 여야한다.
  2. 대칭성 : 객체 X,y에 대하여 x.equals(y)가 true이면 y.equals(x)도 true 여야한다.
  3. 추이성 : 객체 x,y,z에 대하여 x=y , y=z 이면 x=z도 true 여야한다.
  4. 일관성 : null이 아닌 참조 값x,y에 대하여 x.equals(y)는 항상 true거나 false여야한다.
  5. null-아님 : null이 아닌 x에 대하여 x.equals(null) 은 false 이다.

좋은 equals를 구현하는 법

  1. == 연산자를 사용해 자기 자신의 참조인지 확인하라.
  2. instanceof 연산자로 입력이 올바른 타입인지 확인하라. null검사도 해준다.
  3. 입력을 올바른 타입으로 형변환하라.
  4. 입력 객체와 자기 자신의 대응되는 핵심 필드들이 모두 일치하는지 하나씩 검사하라.
  5. 성능을 위해 다를 가능성이 더 크거나, 비용이 싼 필드를 먼저 비교해라.

정리

equals 메소드를 재정의하지 말자. 꼭 필요하다면 5가지 규약을 반드시 지켜야한다.

Comments