Java中variables的内存地址
请看下面的图片。 当我们使用new关键字在java中创build一个对象时,我们从OS获取一个内存地址。
当我们写出out.println(objName)
我们可以看到一个“特殊的”string作为输出。 我的问题是:
- 这是什么输出?
-
如果是由操作系统给我们的内存地址:
a)如何将此string转换为二进制文件?
b)如何获得一个整数variables地址?
这是由“@”字符分隔的类名和System.identityHashCode() 。 身份哈希码表示的是特定于实现的。 它通常是对象的初始内存地址,但是对象可以随时间由VM移动到内存中。 所以(简而言之)你不能依靠任何东西。
在Java中获取variables的内存地址是毫无意义的,因为JVM可以自由地实现对象并将它们移动到合适的地方(在垃圾收集期间,对象可能/将会四处移动)
Integer.toBinaryString()会给你一个二进制forms的整数。
有可能使用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(); }
我设置了这个testing:
//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
结论:
- hashcode!=地址
- toString = class @ HEX(hashcode)
这是Object的“toString()”实现的输出。 如果你的类重写toString(),它将打印完全不同的东西。
这不是内存地址这是classname @ hashcode
哪里
classname =完全限定名称或绝对名称(即包名后跟类名)
hashcode =hex格式(System.identityHashCode(obj)或obj.hashCode()会给你哈希码十进制格式)
你得到的是Object类的toString()方法的结果,或者更准确地说,就是uzay95指出的identityHashCode()。
“当我们用新的关键字在java中创build一个对象时,我们正在从操作系统获取一个内存地址。”
认识到你在Java中所做的一切都是由Java虚拟机来处理是很重要的。 这是JVM提供这些信息。 在主机操作系统的RAM中实际发生的事情完全取决于JRE的实现。
在Java中,当你从一个像Person p = new Person();
这样的类创build一个对象时Person p = new Person();
, p
实际上是指向一个Person
types的内存位置的地址。
当使用statemenet打印p
您将看到一个地址。 new
关键字将创build一个新的内存位置,其中包含class Person
包含的所有实例variables和方法,而p
是指向该内存位置的引用variables。
这对于了解java中的hashcode非常有用:
http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/
像Sunil说的,这不是内存地址 。这只是哈希码
要获得相同的@内容,您可以:
如果hashCode在该类中没有被覆盖:
"@" + Integer.toHexString(obj.hashCode())
如果hashCode被覆盖,你会得到原始值:
"@" + Integer.toHexString(System.identityHashCode(obj))
这经常与内存地址混淆,因为如果你不重写hashCode(),内存地址被用来计算哈希。
toString()是java.lang.Object库中的一个函数,它返回Object引用的String表示,toString()的主体如下
public String toString(Object arg) { return "fully_qualified_className@address"; }
这里的地址是由JVM而不是OS给出的
你可以通过在函数体中提供你自己的实现来覆盖toString()函数