프로그래밍Java 개발자

Java에서 equals() 메서드의 특징을 설명하십시오: 언제, 왜 재정의해야 하는지, 올바르게 구현하는 방법과 잘못된 사용으로 인한 문제는 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

equals() 메서드는 두 객체가 "같은지" 결정합니다. 기본적으로 참조를 비교하지만(즉, ==), 종종 클래스(예: 엔터티, 값 객체)는 데이터에 대한 논리적 비교를 요구합니다.

재정의해야 할 때:

  • 클래스에 객체의 논리적 동등성이 중요한 경우(예: 같은 이메일을 가진 두 사용자는 "같은 사용자")
  • 객체가 equals(및 hashCode)를 사용하는 컬렉션(예: HashSet)에 저장될 것인 경우

요구 사항:

  • equals는 반사적, 대칭적, 추이적, 일관적이어야 하며, null이 아닌 모든 x에 대해 x.equals(null)은 false여야 합니다.
  • equals를 재정의할 경우 hashCode를 반드시 재정의해야 합니다!

예:

public class Person { private String email; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(email, person.email); } @Override public int hashCode() { return Objects.hash(email); } }

트릭 질문

두 객체가 equals()에서 같다면, 그들의 hashCode()는 항상 같아야 하나요?

답변: 네! 이는 Java 계약의 요구 사항입니다. 그러나 반대는 사실이 아닙니다: 동일한 hashCode를 가진 두 객체는 equals()에서 같지 않을 수 있습니다 — 해시 코드가 서로 다른 객체에서 일치할 수 있습니다(충돌).

오류 예:

person1.equals(person2); // true person1.hashCode() != person2.hashCode(); // 오류!

주제에 대한 미숙지로 인한 실제 오류 예


이야기

기업 애플리케이션에서 사용자 엔터티가 HashSet에 포함되었습니다. equals가 재정의되었으나 hashCode는 되지 않았습니다. equals에 영향을 미치는 필드가 수정된 후, HashSet은 이 객체를 "잃었습니다": contains 메서드의 검색 시도는 같은 데이터에 대해서도 false를 반환했습니다.


이야기

IoT 프로젝트에서 엔터티는 일시적으로 id로만 비교되었고, 이후에는 이름을 고려하는 equals로 논리를 변경했습니다. HashMap은 예측할 수 없는 방식으로 작동하고, 키 업데이트 시 중복이 발생했습니다 — equals/hashCode 계약이 구현 버전의 혼동으로 인해 위반되었습니다.


이야기

주문 비교 API를 작성할 때 두 개의 서로 다른 클래스가 각자의 equals를 구현했으며, 하나는 getClass()를 호출하고 다른 하나는 instanceof를 사용했습니다. 이는 주문의 비대칭 비교 및 컬렉션 및 비즈니스 로직 사용 시 버그를 초래했습니다.