为什么没有办法在纯java中获取Object的当前地址? 实际上==运算符是如何工作的? 有没有可能比较对不使用此运算符的对象的引用?
答案 0 :(得分:0)
Q1:无法获得obj的mem位置:Java的原始创建者认为这对语言来说不是必需的。此外,Java现在已经是一种古老/古老的语言,它从未被添加到语言中,这意味着没有人需要它。
Q2。 how == works:如果堆栈上的两个值是相同的值,则返回true。我相信java语言规范要求这两个对象/原型具有相同的类型。我不知道你是否可以在字节码中破解它...答案可能是JVM特定的。
答案 1 :(得分:0)
Java语言不提供内存中对象的地址。由于垃圾收集器可以自由移动物体,因此没有多大意义。
但是,您可能寻求的是对象的哈希码。在Java中,每个对象都有一个hashCode()函数,默认情况下,相同对象返回相同的数字,不同对象的数字不同。因此,hashCode()有效地为您提供了内存中对象的逻辑地址。您不能像在C语言中那样使用地址来修改内存中的数据,但可以使用其值来比较对象。
由于hashCode()方法可以在对象中被覆盖,java.lang.System类提供了一种方法来检索hashCode()函数的原始值,如果它没有被覆盖:System.identityHashCode
答案 2 :(得分:0)
对于Oracle-JVM:
方法Object.toString()传递一个对象标识符,其模式为< class> @< address>。该方法可以通过一些变通方法调用任意类的实例来提取该地址。
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
class ObjectInfo
{
static long getAddress(Object obj)
{
try
{
final Field IMPL_LOOKUP = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
IMPL_LOOKUP.setAccessible(true);
final MethodHandles.Lookup lkp = (MethodHandles.Lookup) IMPL_LOOKUP.get(null);
final MethodHandle h1 = lkp.findSpecial(Object.class, "toString", MethodType.methodType(String.class), Object.class);
final String result = (String) h1.invoke(obj);
final String[] parts = result.split("@");
return Long.parseLong(parts[1], 16);
}
catch (final Throwable e)
{
e.printStackTrace();
return 0;
}
}
}
注意:此处未完成标识符地址与Object的内存地址一致的证据。