Java中variables的内存地址

请看下面的图片。 当我们使用new关键字在java中创build一个对象时,我们从OS获取一个内存地址。

当我们写出out.println(objName)我们可以看到一个“特殊的”string作为输出。 我的问题是:

  1. 这是什么输出?
  2. 如果是由操作系统给我们的内存地址:

    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实际上是指向一个Persontypes的内存位置的地址。

当使用statemenet打印p您将看到一个地址。 new关键字将创build一个新的内存位置,其中包含class Person包含的所有实例variables和方法,而p是指向该内存位置的引用variables。

像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()函数