Java中的原始类型是否存在哈希码/堆地址?

我试图在堆上找到一些近似值来解决,你们给了我一个函数
System.IdentityHashCode(Object)
。 问题是 - 这个函数不适合原始类型。我会解释原因。 我作为输入Java编译程序 - 类文件。我的目标是绘制一些图表,其中包含有关时间之间变量访问的一些信息。我不知道代码如何提前查看,我的策略是为每个LOAD和STORE指令检测我自己的字节码。我正在使用ASM Java Bytecode Instrumentation。 因此,我做不了类似的事情:
identityHashCode(Integer.valueOf(...))
因为我没有迹象表明类型是int,double,long等。 我希望能够在同一个类的不同实例之间进行确定: 例如 :
class foo {
int a;
}
foo b;
foo c;
b.a++;
c.a++;
但是当涉及字节码时,名称“b”/“c”与属性a之间没有关系。所有我“看到”的是a增加了。两者都算是一个!如果那是
Object a
我可以使用System.identityHashCode()来区分它们。但我不能。 为了使自己清楚,请查看以下示例:
package manipulate;

public class Test {
        int c;
        public static void main(String[] args) {
            Test a=new Test();
            Test b=new Test();
            a.c++;
            b.c++;
        }
    }
将被翻译(主函数)到以下字节码:
   L0
    LINENUMBER 7 L0
    NEW manipulate/Test
    DUP
    INVOKESPECIAL manipulate/Test.<init>()V
    ASTORE 1
   L1
    LINENUMBER 8 L1
    NEW manipulate/Test
    DUP
    INVOKESPECIAL manipulate/Test.<init>()V
    ASTORE 2
   L2
    LINENUMBER 9 L2
    ALOAD 1
    DUP
    GETFIELD manipulate/Test.c : I
    ICONST_1
    IADD
    PUTFIELD manipulate/Test.c : I
   L3
    LINENUMBER 10 L3
    ALOAD 2
    DUP
    GETFIELD manipulate/Test.c : I
    ICONST_1
    IADD
    PUTFIELD manipulate/Test.c : I
   L4
    LINENUMBER 11 L4
    RETURN
正如你所看到的,我在堆栈上得到的只是整数c的值。因此,鉴于代码,我无法确定这两个c之间!     
已邀请:
  我得到的是java字节码。我没有b或c,我不知道他们。我只有堆栈上的a值 如果堆栈上有局部变量,则它们具有可变数字。这些数字是堆栈帧的本地数据,方法正在执行,如果它们具有相同的数字,则两个变量是相同的。 如果在评估(参数/操作数/结果)堆栈中有两个原始值,如果它们在同一堆栈索引中同时存在,则它们是相同的(与变量类似)。 在您的示例中,您会看到两个
GETFIELD manipulate/Test.c : I
指令分别对堆栈上的当前值进行操作(由
ALOAD 1
ALOAD 2
放置)。此当前值是变量所属的对象,因此您可以在此处插入此对象的计数代码(首先执行DUP)。     
基元没有身份。它们按价值进行比较,而不是参考。 局部变量中的基元的内存中的地址可能位于寄存器或堆栈中,并且数组或对象的基元成员的位置与其父项的堆地址相关。 Java没有提供任何标准化的内存访问设施,并且像
System.identityHashCode
这样的替代方案不会扩展到它们。 用原语调用
System.identityHashCode
将导致发生虚假拳击,这将产生无意义的结果。 如果你真的需要知道原始成员的位置,你可以编写带有JNI绑定的C代码来获取java对象的句柄,获取指针,并将其转换为正确宽度的java整数类型,但是你最好的打赌可能会找到一些其他方法去做你想做的事情。 另一个选择是使用现有的java调试器钩子:http://download.oracle.com/javase/6/docs/technotes/guides/jpda/architecture.html#jdi     
我不确定我是否理解这个问题,你想知道b.a是否与c.a的变量相同? 在您的情况下,如果b == c,b.a将与c.a相同。如果声明一个静态,它将在foo的所有实例之间共享。     
当你询问内存地址,并获得identityhashCode答案时,关键短语是“一些近似”。无法保证此值将是内存地址,甚至最积极的断言是它是从地址到整数的映射。你绝对无法可靠地确定Java中对象的地址,甚至不应该考虑尝试使用原语。首先,不能保证编译器不会移动它们。甚至没有保证变量有地址。 如果要确定两个对象是否相同,可以使用“==”。对于原语来说这个问题甚至没有意义,你不应该这样做。     

要回复问题请先登录注册