equals 메소드의 오버라이딩의 경우 생각보다 간단하지 않다. 아래 조건 중 어느 하나라도 만족하면 그냥 상속받은 그대로 사용하는 것이 낫다.

  • 클래스의 각 인스턴스가 본래부터 유일한 경우
    • 인스턴스가 갖는 값보다 활동하는 개체임을 나타내는 것이 더 중요한 Thread와 같은 클래스가 해당되며 이런 것들은 놀리적인 비교가 의미가 없다. 그래서 그냥 Object equals를 사용하면 된다.
  • 두 인스턴스가 논리적으로 같은지 검사하지 않아도 되는 클래스
    • 굳이 두 인스턴스를 비교할 필요 없으면 만들지 말자.
  • 수퍼 클래스에서 equals 메소드를 이미 오버라이딩 했고 그 메소드를 그대로 사용해도 좋은 경우.
    • Set 인터페이스를 구현하는 대부분의 클래스들은 AbstractList로부터, Map의 경우는 AbstractMap에서 상속 받아 사용한다.
  • private이나 패키지 전용 클래스라서 이 클래스의 equals 메소드가 절대 호출되지 않아야 할 경우.
    • 우연히 호출될 수 있는 그런 상황에서는 다음과 같이 equals메소드를 반드시 오버라이딩해서 호출되지 않도록 한다.

열거형(enum) 같은 경우 오버라이드를 할 필요가 없다. 그리고 equals를 오버라이딩 하는 이유는 객체 참조만으로 인스턴스가 동일한지 여부를 판단하는게 아니라, 인스턴스가 갖는 값을 비교해서 논리적으로 같은지 판단할 필요가 있을 때 하는 것이다.

뭐.. 굳이 오버라이딩을 해서 구현하겠다면 아래의 규칙은 지켜야 한다.

  • 재귀적(Reflexive) : null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 반드시 true를 반환해야 한다.
  • 대칭적(Symmetric) : null이 아닌 모든 참조 값 x와 y에 대해, y.equals(x) 가 true를 반환한다면 x.equals(y)도 반드시 true를 반환해야 한다.
  • 이행적(Transitive) : null이 아닌 모든 참조 값 x, y, z에 대해, 만일 x.equals(y)가 true를 반환하고 y.equals(z)가 true를 반환한다면 x.equals(z)도 반드시 true를 반환해야 한다.
  • 일관적(Consistent) : null이 아닌 모든 참조 값 x와 y에 대해, equals 메소드에서 객체 비교 시 사용하는 정보가 변경되지 않는다면, x.equals(y)를 여러 번 호출하더라도 일관성 있게 true 또는 false를 반환해야 한다.
  • null이 아닌 모든 참조 값 x에 대해, x.equals(null)은 반드시 false를 반환해야 한다.

 

 

Posted by 서오석
,