[Effective Java] item 10 : equals는 일반 규약을 지켜 재정의하라

DEINGVELOP·2022년 11월 2일
0

Effective Java

목록 보기
3/19

아이템 10부터는 오브젝트의 메소드를 다룬다.

모든 Class는 암묵적으로 Object를 상속받는다. 그 Object들의 메소드들을 오바라이딩으로 구현할 수 있는데, Finalize는 아이템 8에서 다루었으니 그 외의 메소드들을 살펴보겠다.

Equals

equals가 필요 없는 경우

  • 필요하지 않은 경우 equals를 재정의하지 않는 것이 최선

  • 다음과 같은 경우에는 equals를 재정의할 필요가 없다.

    • 각 인스턴스가 본질적으로 고유하다. (ex: enum 등)
    • 인스턴스의 '논리적 동치성'을 검사할 필요가 없다. (ex: 문자열)
    • 상위 클래스에서 재정의한 equals가 하위 클래스에도 적절하다. (ex: list, set, map도 각 상위클래스가 equals를 정의하고 있다.)
    • 클래스가 private이거나 package-private이고, equals 메소드를 호출할 일이 없다.

equals가 필요한 경우

  • 논리적 동치성 검사가 필요한 경우

equals 규약

  • 반사성 : A.equals(A) == true

  • 대칭성 : A.equals(B) == B.equals(A)

    📍 대칭성의 위배

     public final class CaseInsensitiveString {
        private final String s;
     
     public CaseInsensitiveString(String s) {
         this.s = Objects.requireNonNull(s);
        }
      
        // 대칭성 위배!
        @Override public boolean equals(Object o) {
            if (o instanceof CaseInsensitiveString)
                return s.equalsIgnoreCase(
                        ((CaseInsensitiveString) o).s);
            if (o instanceof String)  // 한 방향으로만 작동한다!
                return s.equalsIgnoreCase((String) o);
            return false;
        }
    }
        ```
    👉🏻 즉, 다른 타입을 비교하기 시작하면 문자가 복잡해지고 대칭성이 깨질 수 있다. 
  • 추이성 : A.equals(B) && B.equals(C)A.equals(B)

    📍 추이성의 위배

     public class ColorPoint extends Point {
        private final Color color;
        
        public ColorPoint(int x, int y, Color color) {
            super(x, y);
            this.color = color;
        }
    
        // 코드 10-3 잘못된 코드 - 추이성 위배! (57쪽)
        @Override public boolean equals(Object o) {
            if (!(o instanceof Point))
                return false;
    
            // o가 일반 Point면 색상을 무시하고 비교한다.
            if (!(o instanceof ColorPoint))
                return o.equals(this);
    
            // o가 ColorPoint면 색상까지 비교한다.
         
              return super.equals(o) && ((ColorPoint) o).color == color;
        }
        ```
  • 일관성 : A.equals(B) == A.equals(B)

  • Not null : A.equals(null) == false

0개의 댓글