4

认为

Integer integerA = 500;

我想打印返回的参考。

4

7 回答 7

4

要将对象的引用作为数字获取,您可以在支持它的 JVM 上使用 Unsafe。您可以将引用放在一个数组中,并使用 Unsafe.getInt() 访问它以获取 32 位引用(注意:大多数 64 位 JVM 将使用 32 位引用)或 Unsafe.getLong() 这将访问引用为一个数字,但如果发生 GC 并且对象被移动,它可能会在你得到它后立即改变。

另一个复杂之处在于 CompressedOops 意味着对象的索引可以以多种不同的方式进行转换。为简单起见,我建议使用 4 GB 到 26GB 的堆。对于这些大小,您将地址移动<< 3以获取地址。

顺便说一句,您可以使用 Unsafe.putInt(x, 1, hashCode) 覆盖系统 hashCode。;)

于 2013-08-03T10:21:18.403 回答
3

最接近显示引用的是哈希码,因为它是由 Object System.IdentityHashCode() 计算的。当然,Integer 会覆盖 hashCode,因此 Integer 自己的 hashCode() 方法肯定与它的引用无关。

事实上,不能保证 System.IdentityHashCode 与引用有任何关系——它只是一个数字,在为同一个对象计算时总是相同的,也就是说,对于不同的对象,尽可能地不同.

于 2013-08-03T08:22:36.420 回答
2

人们一直在回答关于hashCode(),但hashCode()对于 anInteger是 的值Integer,它与它在内存中的位置无关。另外,一般来说,仅仅因为两个Objects有相同的hashCode()并不意味着它们引用相同的Object

编辑(回应评论)
即使您使用IdentityHashCode(),它提供了 的非覆盖版本hashCode(),您仍然不会获得内存地址。

于 2013-08-03T08:21:36.233 回答
1

我不相信您可以在 Java 中获取对象的实际内存位置(用于打印目的或其他目的)。即使您这样做System.out.println(new Object()),您看到的也不是“参考”位置,而是包含对象哈希码的字符串。

于 2013-08-03T08:12:49.123 回答
1

这会在 Integer 类中打印“toString”方法的重载版本。一般来说,如果一个类没有重载该方法,它会打印类名 + 哈希码。像这样的事情(你必须手工做):

integerA.getClass().getName() + "@" + integerA.hashCode()
于 2013-08-03T08:15:12.747 回答
0

各种类的默认toString方法都涉及到hashCode方法的结果。也许您正在寻找它,因为它是我能想到的最接近“打印参考”的方法。

于 2013-08-03T08:16:50.157 回答
-1

默认实现(如果没有被覆盖)会将对象打印为类似

Integer i = 95;
System.out.println(i.getClass().getName() + "@" + Integer.toHexString(i.hashCode()));
//java.lang.Integer@5f

如果是整数,则该hashCode值与基础值相同。

于 2013-08-03T08:15:44.717 回答