[英]is there hash code / Heap address for primitive types in Java?
我試圖在堆上找到一個近似的地址,你們給了我函數System.IdentityHashCode(Object)
。
問題是-此函數不適用於基本類型。 我會解釋原因。
作為輸入Java編譯程序-類文件。 我的目標是繪制一些圖形,其中包含一些時間之間的變量訪問信息。 我不知道代碼的樣子,我的策略是為每個LOAD和STORE指令設置自己的字節碼。 我正在使用ASM Java字節碼檢測。
因此,我無法執行以下操作:
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沒有提供任何標准化的內存訪問工具,並且諸如System.identityHashCode
類的替代項也沒有擴展到它們。
用原System.identityHashCode
用System.identityHashCode
將導致發生虛假裝箱,這將產生無意義的結果。
如果您確實需要了解原始成員的位置,則可以編寫具有JNI綁定的C代碼以獲取Java對象的句柄,獲取指針,並將其轉換為寬度合適的Java整數類型,但是最好最好是找到其他方法來做您想做的事情。
另一種選擇是使用現有的Java調試器掛鈎: http : //download.oracle.com/javase/6/docs/technotes/guides/jpda/architecture.html#jdi
我所擁有的是java bytecode。 我沒有b或c,我不知道它們。 我在堆棧上只有a的值
如果堆棧上有局部變量,則它們具有變量號。 這些數字對於在其中執行方法的堆棧框架來說是本地的,並且如果兩個變量具有相同的數字,則它們是相同的。
如果在評估(參數/操作數/結果)堆棧中有兩個原始值,則如果它們在同一堆棧索引中同時存在,則它們是相同的(含義與變量相同)。
在您的示例中,您看到兩個GETFIELD manipulate/Test.c : I
指令均對堆棧上的當前值(由ALOAD 1
或ALOAD 2
放置在ALOAD 2
)進行操作。 當前值是變量所屬的對象,因此您可以在其中插入該對象的計數代碼(首先執行DUP)。
我不確定我是否理解這個問題,您想知道ba實際上是否與ca相同?
在您的情況下,如果b == c,ba將與ca相同。 如果聲明一個靜態變量,它將在foo的所有實例之間共享。
當您詢問內存地址並得到identityhashCode答案時,關鍵短語是“某種近似值”。 不能保證此值將是內存地址,甚至最激進的斷言是它是從地址到整數的映射 。 您絕對不能可靠地確定Java中對象的地址,甚至不應該考慮嘗試使用基元。 一方面,不能保證編譯器不會移動它們。 甚至不能保證變量有地址。
如果要確定兩個對象是否相同,可以使用“ ==”。 這個問題甚至與基元都沒有意義,因此您不應該這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.