- 목차
- equals와 hashCode는 모든 Java 객체의 부모 객체인 Object 클래스에 정의되어 있다.
- 그렇기 때문에 Java의 모든 객체는 Object 클래스에 정의된 equals와 hashCode 함수를 상속
equals와 hashCode
- 예를 들어, 아래와 같이 Menu 클래스가 있다 가정해보자.
public class Menu {
private final String name;
private final int price;
public Menu(final String name, final int price) {
this.name = name;
this.price = price;
}
}
- name과 price 값이 똑같은 두 Menu 객체를 비교한다면?
@Test
@DisplayName("같은 객체를 equals 비교")
void equals() {
//given
Menu friedChicken = new Menu("치킨", 16000);
Menu friedChicken2 = new Menu("치킨", 16000);
//when & then
assertThat(friedChicken).isEqualTo(friedChicken2);
}
- 테스트가 실패했다. 그 이유는 두 객체의 주소 값이 다르기 때문이다.
- 즉, equals 메서드는 주소 값이 다른 객체는 서로 다른 객체로 판단한다.
- 두 객체를 같도록 하려면 Menu 클래스에 equals 메서드를 재정의 해야 한다.
public class Menu {
private final String name;
private final int price;
public Menu(final String name, final int price) {
this.name = name;
this.price = price;
}
// equals 재정의
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Menu))
return false;
Menu menu = (Menu)o;
return price == menu.price && Objects.equals(name, menu.name);
}
}
- equals 메서드를 재정의 후 다시 테스트 코드를 실행하면 테스트가 통과한다.
- @Override로 재정의 하지 않으면 그 클래스의 인스턴스는 오직 자기 자신 과만 같게 된다.
- 꼭 필요한 경우(VO)가 아니면 equals를 재정의 하지 않는다.
- 대부분의 경우 Object의 equals 메서드가 원하는 비교를 정확히 수행한다.
- 양질의 equals 메서드 구현 방법
- == 연산자를 사용해 입력이 자기 자신의 참조인지 확인한다.
- instanceof 연산자로 입력이 올바른 타입인지 확인한다.
- 입력을 올바른 타입으로 형변환한다.(2번에서 instanceof 검사를 했으니 100% 성공한다.)
- 입력 객체와 자기 자신의 대응되는 '핵심' 필드들이 모두 일치하는지 하나씩 검사한다.
- equals를 재정의할 땐
hashCode도 반드시 재정의 한다.
equals()
- Object 클래스의 정의된 equals()는 다음과 같다.