web-dev-qa-db-ja.com

クラスでデフォルトの.equalsと.hashCodeはどのように機能しますか?

自分のクラスがあるとしましょう

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

いくつかの属性とメソッドがあります。 equalsを実装せず、hashCodeを実装しません。

EqualsとhashCodeを呼び出したら、デフォルトの実装は何ですか?オブジェクトクラスから?そして、彼らは何ですか?デフォルトの等号はどのように機能しますか?デフォルトのhashCodeはどのように機能し、何が返されますか? ==は同じオブジェクトを参照しているかどうかを確認するだけなので、簡単ですが、equals()メソッドとhashCode()メソッドはどうでしょうか?

101
alexeypro

はい、デフォルトの実装はオブジェクトです(一般的には、equalsやhashCodeを再定義したクラスから継承する場合は、代わりにその実装を使用します)。

ドキュメントから:

equals

クラスObjectのequalsメソッドは、オブジェクトで最も識別可能な等価関係を実装します。つまり、null以外の参照値xおよびyに対して、このメソッドは、xおよびyが同じオブジェクトを参照する場合にのみtrueを返します(x == yの値はtrueです)。

hashCode

合理的に実用的である限り、Objectクラスによって定義されたhashCodeメソッドは、個別のオブジェクトに対して個別の整数を返します。 (通常、これはオブジェクトの内部アドレスを整数に変換することで実装されますが、この実装手法はJavaTMプログラミング言語では必要ありません。)

91

JVM実装のいずれかで Object から:

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

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

どちらの場合も、問題のオブジェクトのメモリアドレスを比較するだけです。

46
Brad Mace

Objectにはequals()hashCode()のデフォルトの実装があります。独自の実装を提供しない場合は、それらが使用されます。 equals()の場合、これは_==_比較を意味します。オブジェクトは、まったく同じオブジェクトである場合にのみ等しくなります。 hashCode()の場合、 Javadoc に適切な説明があります。

詳細については、「効果的なJava」、 第3章 (pdf)、項目8を参照してください。

10
Jorn

はい、クラスは暗黙的にObjectを拡張するため、Objectクラスから。 equalsは、単にthis == objを返します。 hashCode実装はネイティブです。単なる推測-オブジェクトへのポインタを返します。

1
khachik

独自の実装を提供しない場合、Objectから派生したものが使用されます。クラスインスタンスをHashSet(hashCode()を実際に使用する任意のコレクション)、またはオブジェクトの等価性をチェックする必要があるもの(つまり、HashSetのcontains()メソッド)に配置する予定がない限り、問題ありません。そうでなければ、それがあなたが求めているものである場合、それは正しく動作しません。

HashCodeBuilder および EqualsBuilder from Apache Commons Lang のおかげで、これらのメソッドの独自の実装を提供するのは非常に簡単です。

1
Paweł Dyda

IBMの developerworks のコメント:

このデフォルトの実装では、2つの参照は、まったく同じオブジェクトを参照する場合にのみ等しくなります。同様に、Objectが提供するhashCode()のデフォルトの実装は、オブジェクトのメモリアドレスを整数値にマッピングすることにより導出されます。

ただし、特定のベンダーのJavaバージョンの正確な実装の詳細を確認するには、おそらくソースとして利用するのが最善です(利用可能な場合)

0
brabster