下の写真をご覧ください。new
キーワードを使用してJavaでオブジェクトを作成すると、OSからメモリアドレスが取得されます。
書くout.println(objName)
と、「特別な」文字列が出力として表示されます。私の質問は:
- この出力は何ですか?
OSから提供されたメモリアドレスの場合:
a)この文字列をバイナリに変換するにはどうすればよいですか?
b)整数変数のアドレスを1つ取得するにはどうすればよいですか?
下の写真をご覧ください。new
キーワードを使用してJavaでオブジェクトを作成すると、OSからメモリアドレスが取得されます。
書くout.println(objName)
と、「特別な」文字列が出力として表示されます。私の質問は:
OSから提供されたメモリアドレスの場合:
a)この文字列をバイナリに変換するにはどうすればよいですか?
b)整数変数のアドレスを1つ取得するにはどうすればよいですか?
回答:
これは、「@」文字で区切られたクラス名とSystem.identityHashCode()です。IDハッシュコードが表す内容は実装固有です。多くの場合、これはオブジェクトの初期メモリアドレスですが、オブジェクトは時間の経過とともにVMによってメモリ内で移動できます。したがって、(簡単に言えば)それが何かであることを信頼することはできません。
変数のメモリアドレスを取得することは、Java内では意味がありません。JVMはオブジェクトを実装し、適切と思われるようにオブジェクトを移動できるからです(ガベージコレクション中にオブジェクトが移動する可能性があります)。
Integer.toBinaryString()は、バイナリ形式の整数を提供します。
identityHashcode
、これは無意味ではありません。:)
それを使用することは可能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
結論:
これはメモリアドレスではありません これはclassname @ hashcodeです
どこ
classname =完全修飾名または絶対名(つまり、パッケージ名の後にクラス名が続く)
ハッシュコード= 16進形式(System.identityHashCode(obj)またはobj.hashCode()は10進形式のハッシュコードを提供します)
スニルが言ったように、これはメモリアドレスではありません。これは単なるハッシュコードです
同じ@コンテンツを取得するには、次の方法があります。
そのクラスでhashCodeがオーバーライドされていない場合:
"@" + Integer.toHexString(obj.hashCode())
hashCodeがオーバーライドされている場合は、次のようにして元の値を取得します。
"@" + Integer.toHexString(System.identityHashCode(obj))
これは、メモリアドレスと混同されることがよくあります。hashCode()をオーバーライドしない場合、メモリアドレスはハッシュの計算に使用されるためです。
これはJavaのハッシュコードについて知るのに役立ちます:
http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/
Javaでは、のようなクラスからオブジェクトを作成する場合Person p = new Person();
、p
は実際にはのタイプを指すメモリ位置のアドレスですPerson
。
statemenetを使用して印刷p
すると、アドレスが表示されます。new
キーワードはに含まれているすべてのインスタンス変数およびメソッドを含む新しいメモリ位置せるclass Person
とp
、そのメモリ位置を指す参照変数です。