[Effective Java 3rd] 아이템10~12

Mr.Sir·2022년 6월 7일
0

Effective Java 스터디

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

  • equals 메서드를 재정의해야 할 때
    • 논리적 동치성을 확인해야 할 때 (Integer, String 같은 값 클래스)
      equals가 논리적 동치성을 확인하도록 재정의해두면, 그 인스턴스는 값을
      비교하길 원하는 프로그래머의 기대에 부응, Map의 키와 Set의 원소로 사용할 수 있음.
  • 재정의할 때 지킬 일반 규약
    • 반사성 : null이 아닌 모든 참조 값 x에 대해 x.equals(x)는 참
    • 대칭성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)가 참이면
      y.equals(x)도 참이다.
    • 추이성 : null이 아닌 모든 참조 값 x,y,z에 대해 x.equals(y)가 참이고
      y.equals(z)도 참이면 x.equals(z)도 참이다.
    • 일관성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)를 반복해서
      호출하면 항상 참을 반환하거나 항상 거짓을 반환한다.
    • null-아님 : null이 아닌 모든 참조 값 x에 대해 x.equals(null)은 거짓이다.
  • 구현 방법
    • == 연산자를 사용해 입력이 자기 자신의 참조인지 확인.
    • instanceof 연산자로 입력이 올바른 타입인지 확인.
    • 입력을 올바른 타입으로 형변환 한다.
    • 입력 객체와 자기 자신의 대응되는 '핵심'필드들이 모두 일치하는지 하나씩 검사.
      • float와 double을 제외한 기본 타입 필드는 == 연산자로 비교하고,
        참조타입 필드는 각각의 equals 메서드로, float와 double 필드는
        각각 정적 메서드인 Float.compare(float, float)와
        Double.compare(double, double)로 비교한다.
        Float.NaN, -0.0f, 특수한 부동소수 값 등을 다뤄야 하기 때문!

자바 라이브러리에도 구체 클래스를 확장해 값을 추가한 클래스가 종종 있다.

java.sql.Timestamp의 equals는 대칭성을 위배.
java.net.URL의 equals는 주어진 URL과 매핑된 호스트의 IP 주소를 이용해 비교한다. 일반규약을 어김

equals를 다 구현했다면 대칭적인지, 추이성이 있는지, 일관적인지 확인하라.

Google의 AutoValue 프레임워크 : equals(hashCode)를 작성하고 테스트를 대신해줄 오픈소스.


아이템11 equals를 재정의하려거든 hashCode도 재정의하라.

equals를 재정의한 클래스 모드에서 hashCode도 재정의해야 한다.
그렇지 않으면 hashCode 일반 규약을 어기게 되어 해당 클래스의 인스턴스를
HashMap이나 HashSet 같은 컬렉션의 원소로 사용할 때 문제를 일으킬 것이다.
논리적으로 같은 객체는 같은 해시코드를 반환해야 한다.

Object의 API 문서에 기술된 일반 규약을 따라야 하며,
서로 다른 인스턴스라면 되도록 해시코드도 서로 다르게 구현해야 한다.


아이템12 toString을 항상 재정의하라.

모든 구체 클래스에서 Object의 toString을 재정의하라.
상위 클래스에서 이미 알맞게 재정의한 경우는 예외.
toString을 재정의한 클래스는 사용하기에 즐겁고 그 클래스를 사용한 시스템을
디버깅하기 쉽게 해준다.
toString은 해당 객체 관한 명확하고 유용한 정보를 읽기 좋은 형태로 반환해야 한다.

profile
Deepveloper

0개의 댓글