5

このプログラムを同じマシンで継続的に実行します。

class Test {
    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test.hashCode());
    }
}

結果は、自分のマシン(Windows 7 64ビット)でプログラムを実行するたびに同じです:4384790

別のマシン(Windows Server 2008、64ビット)では、ほとんどの場合、:1671711が表示されます。ただし、結果が11394033になる場合もあります。

私のマシンでは、Java HotSpot(TM)クライアントVM 1.6.0_26/1.6.0_33でプログラムを実行しています。

Objectクラスのドキュメントを読みました。

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

しかし、hashCode()が実際にオブジェクトの内部アドレスを整数に変換することによって実装されている場合、JavaVMが実行するたびにテストオブジェクトに同じアドレスを割り当てる理由がわかりません。

デフォルトのhashCode()がどのように動作するかは正確にわかっていますか?

4

2 に答える 2

5

詳細はJVM固有です。さらに、一部の(ほとんど?)JVMは複数のhashCode()アルゴリズムをサポートしています(JVMを起動するときに、使用するアルゴリズムを選択できます)。

興味深いことに、これらのアルゴリズムのほとんど(Oracleのデフォルトを含む)は、オブジェクトのアドレスをまったく使用しません。たとえば、JDK7のデフォルトでhashCode()は、グローバル疑似乱数ジェネレーターを使用し、生成された疑似乱数ハッシュコードをオブジェクトのヘッダー内にキャッシュします。

もちろん、疑似乱数ジェネレーターは、同じ方法で初期化された場合、常に同じ数列を返します。

私が過去に行った調査の詳細については、Javaの「内部アドレス」とは何ですか?を参照してください。

于 2013-03-06T09:11:08.190 に答える
3

非カーネルプログラムは絶対メモリアドレスでは機能しません。各プロセスが独自のアドレス空間を取得する仮想メモリを使用します。したがって、プログラムは各実行で同じ場所にデータを配置します。

于 2013-03-06T09:10:09.933 に答える