认为
Integer integerA = 500;
我想打印返回的参考。
要将对象的引用作为数字获取,您可以在支持它的 JVM 上使用 Unsafe。您可以将引用放在一个数组中,并使用 Unsafe.getInt() 访问它以获取 32 位引用(注意:大多数 64 位 JVM 将使用 32 位引用)或 Unsafe.getLong() 这将访问引用为一个数字,但如果发生 GC 并且对象被移动,它可能会在你得到它后立即改变。
另一个复杂之处在于 CompressedOops 意味着对象的索引可以以多种不同的方式进行转换。为简单起见,我建议使用 4 GB 到 26GB 的堆。对于这些大小,您将地址移动<< 3
以获取地址。
顺便说一句,您可以使用 Unsafe.putInt(x, 1, hashCode) 覆盖系统 hashCode。;)
最接近显示引用的是哈希码,因为它是由 Object System.IdentityHashCode() 计算的。当然,Integer 会覆盖 hashCode,因此 Integer 自己的 hashCode() 方法肯定与它的引用无关。
事实上,不能保证 System.IdentityHashCode 与引用有任何关系——它只是一个数字,在为同一个对象计算时总是相同的,也就是说,对于不同的对象,尽可能地不同.
人们一直在回答关于hashCode()
,但hashCode()
对于 anInteger
是 的值Integer
,它与它在内存中的位置无关。另外,一般来说,仅仅因为两个Objects
有相同的hashCode()
并不意味着它们引用相同的Object
。
编辑(回应评论):
即使您使用IdentityHashCode(),它提供了 的非覆盖版本hashCode()
,您仍然不会获得内存地址。
我不相信您可以在 Java 中获取对象的实际内存位置(用于打印目的或其他目的)。即使您这样做System.out.println(new Object())
,您看到的也不是“参考”位置,而是包含对象哈希码的字符串。
这会在 Integer 类中打印“toString”方法的重载版本。一般来说,如果一个类没有重载该方法,它会打印类名 + 哈希码。像这样的事情(你必须手工做):
integerA.getClass().getName() + "@" + integerA.hashCode()
各种类的默认toString
方法都涉及到hashCode
方法的结果。也许您正在寻找它,因为它是我能想到的最接近“打印参考”的方法。
默认实现(如果没有被覆盖)会将对象打印为类似
Integer i = 95;
System.out.println(i.getClass().getName() + "@" + Integer.toHexString(i.hashCode()));
//java.lang.Integer@5f
如果是整数,则该hashCode
值与基础值相同。