请看下面的图片。当我们在Java中用new
关键字创建对象时,我们正在从OS获取内存地址。
编写时,out.println(objName)
我们可以看到一个“特殊”字符串作为输出。我的问题是:
- 这是什么输出?
如果是操作系统给我们的内存地址:
a)如何将该字符串转换为二进制?
b)如何获得一个整数变量地址?
请看下面的图片。当我们在Java中用new
关键字创建对象时,我们正在从OS获取内存地址。
编写时,out.println(objName)
我们可以看到一个“特殊”字符串作为输出。我的问题是:
如果是操作系统给我们的内存地址:
a)如何将该字符串转换为二进制?
b)如何获得一个整数变量地址?
Answers:
那是类名和System.identityHashCode(),用'@'字符分隔。身份哈希码表示的是特定于实现的。它通常是对象的初始内存地址,但是随着时间的推移,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 =完全限定名称或绝对名称(即,包名称后跟类名称)
hashcode =十六进制格式(System.identityHashCode(obj)或obj.hashCode()将为您提供十进制格式的哈希码)
在Java中,当您从此类创建对象时Person p = new Person();
,p
实际上是指向的类型的内存位置的地址Person
。
使用statemenet进行打印时,p
您会看到一个地址。的new
键字,使包含所有这些都包括在实例变量和方法的新的存储位置class Person
和p
所指向的存储器位置的参考变量。