본문 바로가기
  • soobinhand의 기술 블로그
도서/이펙티브 자바 - Joshua Bloch

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

by soobinhand 2022. 1. 27.
728x90

equals를 재정의하지 않는 것이 최선일 때.

  • 각 인스턴스가 본질적으로 고유하다.
  • 인스턴스의 '논리적 동치성'을 검사할 일이 없다.
  • 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.
  • 클래스가 private이거나 package이고 equals 메서드를 호출할 일이 없다.

equals를 재정의할 때는 반드시 일반 규약을 따라야 한다. 다음은 Object 명세에 적힌 규약이다.

  • 반사성. x=x여야한다.
  • 대칭성. x=y라면 y=x여야 한다.
  • 추이성. x=y이고 y=z라면 x=z여야 한다.
  • 일관성. x=y를 반복해서 호출해도 항상 값은 같아야 한다.
  • null-아님. x=null은 무조건 false다.

이러한 equals 규약을 어기면 그 객체를 사용하는 다른 객체들이 어떻게 반응할지 알 수 없다.

 

구체 클래스를 확장해 새로운 값을 추가하면서 equals 규약을 만족시킬 방법은 존재하지 않는다.

 

양질의 equals 메소드 구현 방법을 단계별로 정리한다.

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

equals를 다 구현했다면 세 가지를 자문해보자. 대칭적인가? 추이성이 있는가? 일관적인가?

 

equals를 재정의할 땐 hashCode도 반드시 재정의하자.

너무 복잡하게 해결하려 들지 말자.

 

핵심 정리

꼭 필요한 경우가 아니면 equals를 재정의하지 말자. 많은 경우에 Object의 equals가 여러분이 원하는 비교를 정확히 수행해준다. 재정의해야 할 때는 그 클래스의 핵심 필드 모두를 빠짐없이 다섯 가지 규약을 확실히 지켜가며 비교해야 한다.

 

관련 코드

 

GitHub - Soobinhand/effective_java: 이펙티브 자바

이펙티브 자바. Contribute to Soobinhand/effective_java development by creating an account on GitHub.

github.com

 

728x90

댓글