기본 .equals 및 .hashCode가 내 수업에서 어떻게 작동합니까?


106

나만의 수업이 있다고 해

public class MyObj { /* ... */ }

몇 가지 속성과 방법이 있습니다. equals를 구현하지 않고 hashCode를 구현하지 않습니다.

equals와 hashCode를 호출하면 기본 구현은 무엇입니까? Object 클래스에서? 그리고 그들은 무엇입니까? 기본값은 어떻게 작동합니까? 기본 hashCode는 어떻게 작동하며 무엇을 반환합니까? == 동일한 객체를 참조하는지 확인하므로 쉽습니다. 그러나 equals () 및 hashCode () 메서드는 어떻습니까?

답변:


94

예, 기본 구현은 Object입니다 (일반적으로 말하면 equals 및 / 또는 hashCode를 재정의 한 클래스에서 상속하는 경우 대신 해당 구현을 사용합니다).

문서에서 :

equals

Object 클래스에 대한 equals 메소드는 객체에 대해 가능한 가장 구별되는 등가 관계를 구현합니다. 즉, null이 아닌 참조 값 x 및 y에 대해이 메서드는 x와 y가 동일한 객체를 참조하는 경우에만 true를 반환합니다 (x == y는 true 값을 가짐).

hashCode

합리적으로 실용적인만큼 Object 클래스에 의해 정의 된 hashCode 메서드는 고유 한 개체에 대해 고유 한 정수를 반환합니다. (이것은 일반적으로 객체의 내부 주소를 정수로 변환하여 구현되지만 JavaTM 프로그래밍 언어에서는이 구현 기술이 필요하지 않습니다.)


50

에서 ObjectJVM을 구현 중 하나 :

public boolean equals(Object object) {
    return this == object;
}

public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}

두 경우 모두 해당 객체의 메모리 주소를 비교하는 것입니다.


7
어떤 버전의 JDK에서 왔습니까? In v6u23 ea:public native int hashCode();
khachik

@kha-맞아요, 제가 네이티브 구현 중 하나를 추적하여 실제로 무엇을했는지 확인했다고 생각합니다
Brad Mace

10

Object 에는 equals()및의 기본 구현이 있습니다 hashCode(). 자체 구현을 제공하지 않으면 해당 구현이 사용됩니다. 의 경우 equals()이것은 ==비교를 의미 합니다. 객체는 정확히 동일한 객체 인 경우에만 동일합니다. 들어 hashCode()자바 독은 좋은 설명이있다.

자세한 내용은 효과적인 Java, 3 장 (pdf), 항목 8을 참조하십시오.


1

예, Object클래스가 암시 적으로 Object를 확장하므로 클래스 에서 . equals단순히 반환합니다 this == obj. hashCode구현은 기본입니다. 추측 일뿐입니다. 객체에 대한 포인터를 반환합니다.


2
메모리에있는 개체에 대한 포인터이지만 개체의 메모리 주소가 아닙니다. GC는 메모리에서 객체를 이동할 수 있으며 해시 코드는 동일하게 유지됩니다.
Jeremy

@Jeremy 감사합니다. stackoverflow.com/questions/2427631/… 흥미로울 수 있습니다.
khachik 2010

1

자체 구현을 제공하지 않으면 Object에서 파생 된 구현이 사용됩니다. 클래스 인스턴스를 HashSet (실제로 hashCode ()를 사용하는 모든 컬렉션) 또는 객체의 동등성을 확인해야하는 항목 (예 : HashSet의 contains () 메서드)에 넣을 계획이 아니라면 괜찮습니다. 그렇지 않으면 그것이 당신이 요구하는 것이라면 잘못 작동합니다.

이러한 방법 덕분에 자신의 구현을 제공 할 매우 쉽습니다 HashCodeBuilderEqualsBuilder 에서 아파치 코 몬즈 랭 .


(a) Object 클래스의 기본 구현 인 'equals'가 HashSet에서 올바르게 작동하지 않는 이유는 무엇입니까? 이 페이지의 다른 답변과 모순됩니다. (b) Commons Lang 링크에 감사드립니다.
Basil Bourque 2011

1
@Basil : 모순되지 않는다고 생각합니다. 물론 기본 구현은 어떻게 든 작동하지만 예상 한 방식은 아닙니다. 즉, equals ()는 참조 동등성을 사용하기 때문에 기본 구현의 관점에서 두 개의 동일한 객체는 "다른"것입니다. 결과적으로 세트에 정확히 동일한 두 개의 다른 인스턴스가있을 수 있습니다. 그리고 설정 오히려 일반적인 사용은 중복을 제거 할 때입니다 ...
파블 Dyda

@ PawełDyda : 기본 동작은 일반적으로 변경 가능한 유형에 적합합니다. 경우 Foo와하면 Bar변경 가능한 형태의 두 가지 경우에 대한 참조, 및 방법 (예를 들어 존재 SomeMutatingMethod하는) 등의 Foo.SomeMutatingMethod()영향을주지 않는 Bar것이 않는 동일한 방법으로 Foo, 그 차이가 불균등으로 개체 간주하기에 충분해야한다.
supercat

0

IBM의 developerworks 는 다음과 같이 말합니다.

이 기본 구현에서 두 참조는 정확히 동일한 객체를 참조하는 경우에만 동일합니다. 마찬가지로 Object에서 제공하는 hashCode ()의 기본 구현은 객체의 메모리 주소를 정수 값에 매핑하여 파생됩니다.

그러나 특정 공급 업체의 Java 버전에 대한 정확한 구현 세부 정보를 확인하려면 소스로 보는 것이 가장 좋습니다 (사용 가능한 경우).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.