프로그래밍Java 개발자

Java에서 hashCode() 메서드 재정의 메커니즘은 어떻게 작동하며, 이때 준수해야 할 규칙은 무엇이고, 이러한 규칙을 위반하면 어떤 심각한 버그가 발생할 수 있나요?

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

답변.

hashCode() 메서드의 재정의는 equals()의 재정의와 밀접한 관련이 있으며, 두 메서드는 HashMap, HashSet, Hashtable과 같은 컬렉션에서 객체를 올바르게 사용할 수 있도록 하는 기반을 형성합니다.

규칙:

  • equals()를 재정의하는 경우 반드시 hashCode()도 재정의해야 합니다.
  • equals()가 같은 객체는 동일한 hashCode()를 반환해야 합니다.
  • 오류를 피하기 위해 Objects.hash()와 같은 표준 해시 생성 방법이나 IDE 템플릿을 사용하는 것이 좋습니다.
  • hashCode()는 객체의 "수명" 동안 동일한 값을 반환해야 합니다 (hashCode에 포함된 필드가 변경되지 않는다면).
class User { private String name; public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User user = (User) o; return Objects.equals(name, user.name); } public int hashCode() { return Objects.hash(name); } }

속임수 질문.

질문: "equals()가 다른 두 객체가 동일한 hashCode()를 반환하면 어떻게 되나요? 이게 오류일까요?"

답변: 아닙니다, 이것은 오류가 아닙니다. 해시 코드의 충돌은 해결 가능하고 예상됩니다. 중요한 것은 객체가 equals에 따라 같다면, 그들의 hashCode는 동일해야 한다는 것입니다. equals가 다른 객체들이 동일한 hashCode를 반환하면 컬렉션은 느리게 작동할 수 있지만(충돌 수가 늘어나기 때문) 여전히 올바르게 작동합니다.

주제에 대한 지식 부족으로 인한 실제 오류 사례.


이야기

금융 소프트웨어에서 여러 필드를 기준으로 프로젝트를 비교했지만, equals()만 재정의했습니다. HashSet에 객체를 저장하면서 hashCode()가 재정의되지 않아 기본값으로 작동했기 때문에(각 인스턴스마다 달라짐) 중복이 발생했습니다.


이야기

재고 관리 시스템에서 비즈니스 로직 변경 후 equals()를 확장했지만, hashCode() 업데이트를 잊었습니다. 서로 다른 hashCode를 가진 equals=true인 객체가 HashMap에서 사라졌으며(키로 찾을 수 없음), 이는 큰 재정적 오류로 이어졌습니다.


이야기

웹 애플리케이션에서 hashCode 계산에 변경 가능한 필드를 사용했습니다. 내부 필드 값을 업데이트할 때 해시가 변경되어 객체가 HashSet/HashMap에서 "사라졌습니다": 표준 메서드를 통해 찾거나 삭제할 수 없어 메모리 누수 및 버그로 이어졌습니다.