web-dev-qa-db-ja.com

Javaの変数のメモリアドレス

下の写真をご覧ください。 newキーワードを使用してJavaにオブジェクトを作成すると、OSからメモリアドレスが取得されます。

out.println(objName)と書くと、出力として「特別な」文字列を見ることができます。私の質問は:

  1. この出力は何ですか?
  2. OSから提供されたメモリアドレスの場合:

    a)この文字列をバイナリに変換するにはどうすればよいですか?

    b)1つの整数変数アドレスを取得するにはどうすればよいですか?

alt text

123
uzay95

それはクラス名であり、 System.identityHashCode() は「@」文字で区切られています。 IDハッシュコードが表すものは実装固有です。多くの場合、オブジェクトの初期メモリアドレスですが、オブジェクトはVMによって時間とともにメモリ内を移動できます。そのため、(簡単に)何かに頼ることはできません。

変数のメモリアドレスを取得することはJava内では意味がありません。JVMはオブジェクトを実装し、適切と思われるように移動できるためです(ガベージコレクション中にオブジェクトが移動する場合があります)。

Integer.toBinaryString() は、バイナリ形式の整数を提供します。

148
Brian Agnew

Sun.misc.Unsafeを使用することも可能です。@ Peter Lawreyのこの素晴らしい回答を参照してください-> 参照アドレスを取得する方法はありますか?

PrintAddresses()のコードを使用して:

    public static void printAddresses(String label, Object... objects) {
    System.out.print(label + ": 0x");
    long last = 0;
    int offset = unsafe.arrayBaseOffset(objects.getClass());
    int scale = unsafe.arrayIndexScale(objects.getClass());
    switch (scale) {
    case 4:
        long factor = is64bit ? 8 : 1;
        final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;
        System.out.print(Long.toHexString(i1));
        last = i1;
        for (int i = 1; i < objects.length; i++) {
            final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;
            if (i2 > last)
                System.out.print(", +" + Long.toHexString(i2 - last));
            else
                System.out.print(", -" + Long.toHexString( last - i2));
            last = i2;
        }
        break;
    case 8:
        throw new AssertionError("Not supported");
    }
    System.out.println();
}

私はこのテストを設定しました:

    //hashcode
    System.out.println("Hashcode :       "+myObject.hashCode());
    System.out.println("Hashcode :       "+System.identityHashCode(myObject));
    System.out.println("Hashcode (HEX) : "+Integer.toHexString(myObject.hashCode()));

    //toString
    System.out.println("toString :       "+String.valueOf(myObject));

    printAddresses("Address", myObject);

出力は次のとおりです。

Hashcode :       125665513
Hashcode :       125665513
Hashcode (HEX) : 77d80e9
toString :       Java.lang.Object@77d80e9
Address: 0x7aae62270

結論:

  • ハッシュコード!=アドレス
  • toString = class @ HEX(hashcode)
30
JBE

これは、Objectの「toString()」実装の出力です。クラスでtoString()をオーバーライドすると、まったく異なるものが出力されます。

11
Paul Tomblin

これはメモリアドレスではないこれはclassname @ hashcode

どこ

classname =完全修飾名または絶対名(つまり、パッケージ名の後にクラス名が続く)

ハッシュコード= 16進形式(System.identityHashCode(obj)またはobj.hashCode()は10進形式のハッシュコードを提供します)

5

Sunilが言ったように、これはメモリアドレスではありません。これは単なるハッシュコードです。

同じ@コンテンツを取得するには、次のことができます。

HashCodeがそのクラスでオーバーライドされない場合:

"@" + Integer.toHexString(obj.hashCode())

HashCodeがオーバーライドされた場合、次のようにして元の値を取得します。

"@" + Integer.toHexString(System.identityHashCode(obj)) 

HashCode()をオーバーライドしない場合、ハッシュの計算にメモリアドレスが使用されるため、これは多くの場合、メモリアドレスと混同されます。

2
Topera

取得しているのは、uzay95が指摘しているように、ObjectクラスのtoString()メソッド、より正確にはidentityHashCode()の結果です。

「新しいキーワードを使用してJavaにオブジェクトを作成すると、OSからメモリアドレスが取得されます。」

Javaで行うすべてがJava仮想マシンによって処理されることを理解することが重要です。この情報を提供しているのはJVMです。ホストオペレーティングシステムのRAMで実際に何が起こるかは、JREの実装に完全に依存します。

1
James P.

Javaでは、Person p = new Person();のようなクラスからオブジェクトを作成する場合、pは実際にはPersonのタイプを指しているメモリ位置のアドレスです。

Statemenetを使用してpを印刷すると、アドレスが表示されます。 newキーWordは、class Personに含まれるすべてのインスタンス変数とメソッドを含む新しいメモリロケーションを作成し、pはそのメモリロケーションを指す参照変数です。

1

これはJavaのハッシュコードについて知っておくと便利です:

http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/

0
himnabil