공부기록

아이템 10. equals는 일반 규약을 지켜 재정의하라 본문

JAVA

아이템 10. equals는 일반 규약을 지켜 재정의하라

gracelove91 2019. 11. 29. 22:25
반응형

equals를 재정의 하지 않아도 되는 경우.

  • 각 인스턴스가 본질적으로 고유하다.

    • 예를 들어 Thread처럼 값을 표현하는 게 아닌, 동작하는 개체를 표현하는 클래스
  • 인스턴스의 논리적 동치성을 검사할 일이 없다

  • 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.

    • 예를들어 Set구현체는 AbstractSet이 구현한 equals를 상속받아 쓴다.
  • 클래스가 private이거나 default이고 equals메서드를 호출할 일이 없다.

    • equals 를 호출하는 걸 막으려면 다음과 같이 구현하자.

        @Override
        public boolean equals(Object o) {
          throw new AssertionError();
        }

equals를 재정의 해야하는 경우

  • 논리적 동치성을 확인해야하는데 상위 클래스의 equals가 논리적 동치성을 비교하도록 재정의되지 않았을 때.
    • 주로 Integer와 String처럼 값을 표현하는 클래스가 여기에 해당.

equals 메서드의 일반 규약

  • equals 메서드는 동치관계를 구현하며, 다음을 만족한다
    • 반사성 : null이 아닌 모든 참조 값 x에 대해 x.equals(x)는 true다.
    • 대칭성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)가 true면 y.equals(x) 또한 true다
    • 추이성 : null이 아닌 모든 참조 값 x,y,z에 대해 x.equals(y)가 true이고, y.equals(z)가 true면 x.equals(z) 또한 true다.
    • 일관성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)를 반복해서 호출하면 항상 true 이거나 항상 false여야한다.
    • null 아님 : null이 아닌 모든 참조 값 x에 대해, x.equals(null)은 false다.

equals 메서드 단계별 구현 방법.

  1. == 연산자를 사용해 입력이 자기 자신의 참조인지 확인한다.
  2. instanceof 연산자로 입력이 올바른 타입인지 확인한다.
  3. 입력을 올바른 타입으로 형변환한다.
  4. 입력객체와 자기 자신의 대응되는 핵심 필드들이 모두 일치하는 지 하나 씩 검사한다.

정리.

  • 꼭 필요한 경우가 아니면 equals를 재정의하지 말것. 구현한다면 다섯가지 규약을 확실히 지켜가며 핵심 필드들을 비교해야한다.
반응형