equals 메소드를 위한 효과적인 코드 작성

3475 단어

equals 메서드를 재정의해야 하는 이유



Q: 언제 equals 메서드를 재정의해야 합니까?
A: 클래스가 이를 재정의하지 않고 개체 ID가 평등에 충분하지 않은 경우.
equals의 올바른 구현은 인스턴스 객체가 맵 키 역할을 하거나 예측 가능하고 바람직한 동작으로 요소를 설정하도록 합니다.
equals 방법이 특징:
  • 재귀: 객체는 자신과 같아야 합니다.
  • 대칭: 개체 A가 개체 B와 같으면 개체 B도 개체 A와 같아야 합니다
  • .
  • 추이: A가 B와 같으면 B는 C와 같으므로 A는 C와 같아야 합니다.
  • 일관성: 몇 번을 실행해도 동일한 결과가 반환됩니다.

  • 그리고 OOP 세계에만 존재하는 또 하나의 중요한 특성.
    Lisov 대체 원칙에 따르면 유형의 중요한 속성은 모든 하위 유형에 대해서도 유지되어야 하므로 해당 유형에 대해 작성된 모든 메서드는 해당 하위 유형에서 동일하게 잘 작동해야 합니다.
    그게 무슨 뜻이야?
    예를 들어:

    class A {
       int size;
    }
    
    class B extends A {
        Color color;
    }
    
    A a = new A(1);
    B b = new B(1, Color.RED);
    
    a.equals(b) // should return true
    

    인스턴스화 가능한 클래스를 확장하고 여기에 값 구성 요소를 추가하는 것은 전이 규칙을 쉽게 위반합니다.java.util.Timstamp처럼 java.util.Date에서 확장하고 나노초 필드를 추가합니다.

    null 검사를 수행하고 equal 메소드에서 비교하기 위해 getClass()를 수행하는 일반적인 실수 중 하나입니다. 그러면 equals 메서드가 Lisov 대체 특성을 가질 수 없습니다.
    equals 메서드에서 null 검사가 필요하지 않습니다. 접근자를 가질 수 있도록 우리가 원하는 객체에 캐스트하기만 하면 됩니다.

    public boolean equals(Object o) {
      if (!(o instanceof MyType)) {
          return false;
      }
    }
    

    결론



    고품질equals 방법:
  • == 연산자를 사용하여 인수가 이 개체에 대한 참조인지 확인하십시오. 성능 최적화
  • instanceof를 사용하여 arg의 유형이 올바른지 확인하십시오. null 검사를 수행할 필요가 없습니다.
  • 올바른 유형으로 인수를 캐스트하십시오.
  • arg의 파일이 해당 필드와 일치하는지 확인하십시오. float 또는 double 필드인 경우 Float.compareDouble.compare 메서드를 호출해야 합니다. 필드가 개체 필드인 경우 equals 메서드를 호출합니다. 재귀적으로. NullPointerException 의 가능성을 피하기 위해 Objects.equals(Object, Object) 사용
  • equals 메서드를 작성한 후.
    대칭인가요? 전이적입니까? 일관성이 있습니까?
    AutoValue 프레임워크를 사용하여 hashCodeequals를 더 쉽게 작성하십시오.

    좋은 웹페이지 즐겨찾기