책/Effective Java

[이펙티브 자바] 아이템10: equals는 일반 규약을 지켜 재정의하라

2022. 4. 20. 23:35
목차
  1.  
  2. 선결론
  3. equals를 재정의하지 않아야 할 때
  4. equals를 재정의해야 할 때
  5. equals 메서드를 재정의할 때 따라야 하는 규약 5가지
  6. 양질의 equals 메서드 구현 방법
본문은 Effective Java를 읽고 간단하게 정리한 글입니다. 필요에 따라 생략/수정된 부분이 있을 수 있으며, 내용이 추후 변경될 수 있습니다.

 

선결론

  • 꼭 필요한 경우가 아니면 equals를 재정의하지 말자 -> 대부분의 경우에 Object.equals로 충분
  • 재정의하는 경우엔 아래에서 서술할 규약을 잘 지켜서 할 것

 

equals를 재정의하지 않아야 할 때

  • 각 인스턴스가 본질적으로 고유할 때 -> 객체 식별성(물리적 동치성)을 비교할 때
  • 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없을 때
  • 상위 클래스에서 재정의한 equals가 하위 클래스에도 유효할 때
  • 클래스가 private이거나 package-private이고 equals메서드를 호출할 일이 없을 때

 

equals를 재정의해야 할 때

  • 객체 식별성이 아닌 논리적 동치성을 확인해야 하지만, 상위 클래스의 equals가 이를 충족하지 않을 때 -> 값 클래스(Integer, String, ..)
  • 하지만 값 클래스라 하더라도 값이 같은 인스턴스가 둘 이상 만들어지지 않음을 보장하는 인스턴스 통제 클래스라면 equals 재정의 X -> Enum

 

equals 메서드를 재정의할 때 따라야 하는 규약 5가지

  • 반사성(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다
    • 모든 객체가 null과 같지 않아야 한다

 

양질의 equals 메서드 구현 방법

  1. == 연산자를 사용해 입력이 자기 자신의 참조인지 확인
  2. instanceof 연산자로 입력이 올바른 타입인지 확인
  3. 입력을 올바른 타입으로 형변환
  4. 입력 객체와 자기 자신의 대응되는 '핵심'필드들이 모두 일치하는지 하나씩 검사 -> 하나라도 다르면 false
  5. 대칭적인지? 추이성이 있는지? 일관적인지? 3가지를 자문할 것

 

이중 4번 항목에서 필드를 비교하는 방법에 대해 좀 더 살펴보자

  • float와 double을 제외한 기본 타입 필드는 == 연산자로 비교한다
  • 참조 타입 필드는 각각의 equals 메서드로 비교한다
    • null도 정상 값으로 취급하는 참조 타입 필드의 경우, Objects.equals(Object, Object)로 비교해 NPE 발생을 예방
    • 비교하기에 너무 복잡한 필드를 가진 클래스는 필드의 표준형(canonical form)을 저장해둔 후 표준형끼리 비교
  • float와 double은 각각 Float.compare(float, float)와 Double.compare(double, double)로 비교한다
  • 어떤 필드를 먼저 비교하느냐에 따라 equals의 성능을 좌우 -> cost를 고려하여 비교순서를 정할 것

 

마지막으로 다음 주의사항을 지키자

  • equals를 재정의할 땐 hashCode도 반드시 재정의
  • 너무 복잡하게 메서드 작성 X -> 필드의 동치성만 검사해도 위의 규약을 충분히 지킬 수 있음
  • Object 외의 타입을 매개변수로 받는 equals 메서드는 선언하지 말 것(아래 예시)
@Override public boolean equals(MyClass o) { .. }
저작자표시 비영리 (새창열림)

'책 > Effective Java' 카테고리의 다른 글

[이펙티브 자바] 아이템12: ToString을 항상 재정의하라  (0) 2022.04.26
[이펙티브 자바] 아이템11: equals를 재정의하려거든 hashCode도 재정의하라  (0) 2022.04.22
[이펙티브 자바] 아이템9: try-finally보다는 try-with-resources를 사용하라  (0) 2022.04.20
[이펙티브 자바] 아이템7: 다 쓴 객체 참조를 해제하라  (0) 2022.04.19
[이펙티브 자바] 아이템6: 불필요한 객체 생성을 피하라  (0) 2022.04.18
  1.  
  2. 선결론
  3. equals를 재정의하지 않아야 할 때
  4. equals를 재정의해야 할 때
  5. equals 메서드를 재정의할 때 따라야 하는 규약 5가지
  6. 양질의 equals 메서드 구현 방법
'책/Effective Java' 카테고리의 다른 글
  • [이펙티브 자바] 아이템12: ToString을 항상 재정의하라
  • [이펙티브 자바] 아이템11: equals를 재정의하려거든 hashCode도 재정의하라
  • [이펙티브 자바] 아이템9: try-finally보다는 try-with-resources를 사용하라
  • [이펙티브 자바] 아이템7: 다 쓴 객체 참조를 해제하라
코택
코택
코택
TaxFree
코택
전체
오늘
어제
  • 분류 전체보기 (369)
    • Spring (29)
      • Spring (18)
      • 스프링 핵심 원리 - 고급편 (11)
    • Spring Batch (4)
    • JPA (4)
    • CS (89)
      • 자료구조 (2)
      • 네트워크 (5)
      • 운영체제 (1)
      • 데이터베이스 (4)
      • SQL (7)
      • 알고리즘 이론 (4)
      • 알고리즘 문제 풀이 (66)
    • 웹 (28)
      • React.js (4)
      • Next.js (1)
      • Node.js (14)
      • FastAPI (4)
      • Django (5)
    • 프로그래밍 언어 (45)
      • Python (5)
      • Java + Kotlin (29)
      • JavaScript + TypeScript (11)
    • 테스트코드 (26)
      • ATDD, 클린 코드 with Spring (4)
      • 이규원의 현실 세상의 TDD: 안정감을 주는 코드.. (20)
    • 인프라 (6)
      • AWS (2)
      • Kubernetes (4)
    • 트러블슈팅 (25)
    • 책 (89)
      • Effective Java (54)
      • Effective Kotlin (14)
      • 도메인 주도 개발 시작하기: DDD 핵심 개념 정.. (11)
      • 웹 프로그래머를 위한 데이터베이스를 지탱하는 기술 (6)
      • 도메인 주도 설계 첫걸음 (4)
    • Git (10)
    • 회고 (5)
    • etc (8)

블로그 메뉴

  • 홈
  • 방명록
  • 관리
  • GitHub
  • LinkedIn

공지사항

  • 스킨 관련

인기 글

태그

  • 그래프 탐색
  • fastapi
  • 장고
  • Shortest Path
  • atdd
  • http
  • Git
  • BOJ
  • mysql
  • 깊이 우선 탐색
  • 그래프
  • 브루트포스
  • 파이썬
  • 백준
  • dp

최근 댓글

최근 글

hELLO · Designed By 정상우.
코택
[이펙티브 자바] 아이템10: equals는 일반 규약을 지켜 재정의하라
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.