Java中对象的地址

时间:2015-08-18 19:03:30

标签: java

为什么没有办法在纯java中获取Object的当前地址? 实际上==运算符是如何工作的? 有没有可能比较对不使用此运算符的对象的引用?

3 个答案:

答案 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的内存地址一致的证据。