下の写真をご覧ください。 new
キーワードを使用してJavaにオブジェクトを作成すると、OSからメモリアドレスが取得されます。
out.println(objName)
と書くと、出力として「特別な」文字列を見ることができます。私の質問は:
OSから提供されたメモリアドレスの場合:
a)この文字列をバイナリに変換するにはどうすればよいですか?
b)1つの整数変数アドレスを取得するにはどうすればよいですか?
それはクラス名であり、 System.identityHashCode() は「@」文字で区切られています。 IDハッシュコードが表すものは実装固有です。多くの場合、オブジェクトの初期メモリアドレスですが、オブジェクトはVMによって時間とともにメモリ内を移動できます。そのため、(簡単に)何かに頼ることはできません。
変数のメモリアドレスを取得することはJava内では意味がありません。JVMはオブジェクトを実装し、適切と思われるように移動できるためです(ガベージコレクション中にオブジェクトが移動する場合があります)。
Integer.toBinaryString() は、バイナリ形式の整数を提供します。
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
結論:
これは、Objectの「toString()」実装の出力です。クラスでtoString()をオーバーライドすると、まったく異なるものが出力されます。
これはメモリアドレスではないこれはclassname @ hashcode
どこ
classname =完全修飾名または絶対名(つまり、パッケージ名の後にクラス名が続く)
ハッシュコード= 16進形式(System.identityHashCode(obj)またはobj.hashCode()は10進形式のハッシュコードを提供します)
Sunilが言ったように、これはメモリアドレスではありません。これは単なるハッシュコードです。
同じ@コンテンツを取得するには、次のことができます。
HashCodeがそのクラスでオーバーライドされない場合:
"@" + Integer.toHexString(obj.hashCode())
HashCodeがオーバーライドされた場合、次のようにして元の値を取得します。
"@" + Integer.toHexString(System.identityHashCode(obj))
HashCode()をオーバーライドしない場合、ハッシュの計算にメモリアドレスが使用されるため、これは多くの場合、メモリアドレスと混同されます。
取得しているのは、uzay95が指摘しているように、ObjectクラスのtoString()メソッド、より正確にはidentityHashCode()の結果です。
「新しいキーワードを使用してJavaにオブジェクトを作成すると、OSからメモリアドレスが取得されます。」
Javaで行うすべてがJava仮想マシンによって処理されることを理解することが重要です。この情報を提供しているのはJVMです。ホストオペレーティングシステムのRAMで実際に何が起こるかは、JREの実装に完全に依存します。
Javaでは、Person p = new Person();
のようなクラスからオブジェクトを作成する場合、p
は実際にはPerson
のタイプを指しているメモリ位置のアドレスです。
Statemenetを使用してp
を印刷すると、アドレスが表示されます。 new
キーWordは、class Person
に含まれるすべてのインスタンス変数とメソッドを含む新しいメモリロケーションを作成し、p
はそのメモリロケーションを指す参照変数です。
これはJavaのハッシュコードについて知っておくと便利です:
http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/