72

通常、 のデフォルトの実装はObject.hashCode()、メモリ内のオブジェクトの割り当てられたアドレスの関数です (ただし、これはJLSによって義務付けられていません)。VM がメモリ内でオブジェクトをシャントすることを考えると、System.identityHashCode()オブジェクトの有効期間中に返される値が決して変わらないのはなぜですか?

それが「ワンショット」計算である場合 (オブジェクトhashCodeは 1 回計算され、オブジェクト ヘッダーなどに格納されます)、2 つのオブジェクトが同じものを持つ可能性があることを意味しますidentityHashCodeか?メモリ内の同じアドレス)?

4

5 に答える 5

42

最新の JVM は、値をオブジェクト ヘッダーに保存します。オブジェクトの割り当てに費やされる時間を最小限に抑えるために、値は通常、最初の使用時にのみ計算されると思います (時には数十サイクルまで)。共通の Sun JVM は、すべてのオブジェクトの ID ハッシュ コードが常に 1 になるようにコンパイルできます。

複数のオブジェクトが同じ ID ハッシュ コードを持つことができます。それがハッシュコードの性質です。

于 2009-06-30T11:09:16.920 に答える
16

2 番目の質問への回答として、実装に関係なく、複数のオブジェクトが同じ identityHashCode を持つ可能性があります。

javadoc の文言に関する簡単な説明と、非一意性を示すプログラムについては、バグ 6321873を参照してください。

于 2009-06-30T11:08:56.733 に答える
2

HotSpot のオブジェクトのヘッダーは、クラス ポインターと「マーク」ワードで構成されます。

マーク ワードのデータ構造のソース コードは、markOop.hppファイルにあります。このファイルには、マーク ワードのメモリ レイアウトを説明するコメントがあります。

hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)

ここで、32 ビット システム上の通常の Java オブジェクトの ID ハッシュ コードがマーク ワードに保存され、25 ビット長であることがわかります。

于 2015-06-12T20:29:15.067 に答える
0

ハッシュ関数を実装するための一般的なガイドラインは次のとおりです。

  • 同じオブジェクトは一貫した hashCode を返す必要があり、時間の経過とともに変化したり、変数情報 (乱数または可変メンバー フィールドの値によってシードされたアルゴリズムなど) に依存したりしてはなりません。
  • ハッシュ関数は適切なランダム分布を持つ必要があります。つまり、ハッシュコードをバケットと見なす場合、2 つのオブジェクトは可能な限り異なるバケット (ハッシュコード) にマップする必要があります。2 つのオブジェクトが同じハッシュコードを持つ可能性はほとんどありませんが、発生する可能性はあります。
于 2009-06-30T11:14:04.820 に答える
-4

私の知る限り、これは参照を返すように実装されており、オブジェクトのライフタイムでは決して変更されません。

于 2009-06-30T11:07:26.063 に答える