Last updated
Last updated
Object 클래스의 메서드 중 하나로, 매개변수로 전달된 객체와 자기 자신의 일치 여부를 반환
반드시 필요한 경우가 아니라면 equals를 오버라이딩하지 않는 편이 좋다. 대부분의 클래스는 Object의 equals를 통해 수행하는 비교만으로 충분하기 때문에, 아래의 상황에 해당하는 경우에만
필수 규약을 잘 지켜
오버라이딩하는 편이 좋다.
object의 equals는 전달된 객체와 자기 자신이 물리적으로 동일한 객체인지
를 반환
물리적으로 동일이란, 정확히 같은 메모리 주소를 갖는 객체임을 의미
그러나 서로 다른 메모리 주소에 할당되었어도 의미적으로 같은 객체로 취급되어야 하는 상황이 있을 수도 있으며, 이 경우 equals가 논리적 동일성을 판단하도록 오버라이딩해야 함
Wrapper 클래스의 경우, 서로 다른 메모리 주소를 갖더라도 필드로 포함하는 int 값이 같다면 같은 객체로 취급되어야 함
이외에도 메모리 주소가 달라도 (일부 또는 전체) 필드 값이 같으면 같다고 취급되어야 할 클래스들이 존재할 수 있음
예시 - wrapper 클래스
위 프로그램의 실행 결과는 아래와 같음
==을 통한 비교가 false이므로 두 객체는 서로 다른 메모리 주소를 가짐을 알 수 있으나, equals를 통한 비교의 결과는 true임을 확인할 수 있는데, 이는 Integer 클래스에서 equals 메서드를 아래와 같이 오버라이딩하고 있기 때문
(참고로 new를 통해 Integer를 생성하는 것은 좋은 생성 방식이 아님. 하지만 본 예시에서는 두 객체의 물리적 주소를 다르게 하기 위해 일부러 new를 사용함. valueOf를 통해 생성하는 것이 좋은 방법이지만 위 예제에서 valueOf를 사용하면 ==을 통한 비교 결과도 true이기 때문에 예제가 설명하고자 하는 목적과 맞지 않아 new를 사용)
하위 클래스에서 equals를 오버라이딩하지 않으면 상위 클래스의 equals를 그대로 이용하게 되는데, 이 경우 정보 불충분 등으로 동일성을 제대로 판단하지 못할 수도 있음
예시 - Point와 ColorPoint
다음은 2차원 공간의 점을 나타내는 Point 클래스
이를 상속하는 ColorPoint라는 클래스에서 color 라는 새 정보를 필드로 소유한다고 하면, 상위 클래스인 Point의 equals 만으로는 색상 일치 여부를 알 수 없음
이러한 경우에는 색상 정보까지 포함하여 일치 여부를 판단하도록 equals를 오버라이딩해야 함
반사성
: 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)를 반복해서 호출한 결과는 항상 참이거나 거짓
not null
: null이 아닌 x에 대해 x.equals(null)은 항상 거짓
==를 통한 비교 결과가 참인지 확인 (물리적으로 동일한 경우 무조건 동일)
동일한 클래스/인터페이스의 인스턴스인지 확인 (아니라면 거짓)
명시적으로 형변환한 뒤, 동일해야 하는 필드에 대한 동일 여부 비교
동일할 필요가 없는 필드를 잘 제외하는 것 또한 중요