我對Android 6(ART)上的JNI本機代碼有點問題。我有一種方法可以接收jclass
實例並存儲此類參考以供將來使用。要做到這一點,我需要創建這個jclass
的引用,以便它不會成爲無效後:JNI:如何檢查兩個jclass實例是否實際引用相同的Java類?
std::set<jclass> storedClasses;
void storeClass(jclass cls)
{
TraceLog << "Original jclass:" << cls;
jclass clsRef = (jclass)env.jniEnv()->NewGlobalRef(cls);
TraceLog << "New jclass global reference:" << cls;
storedClasses.insert(clsRef);
}
需要說明的是,我只需要存儲每個類一次(因此的std::set
選擇對於容器 - 它保證所有項目都是唯一的),但實際上NewGlobalRef
每次都創建一個新的,不同的jclass
值。這很有道理,但直到最近我才相信。我不能再使用這個值(它只是一個指針)來確保唯一性。
我如何檢查兩個不同jclass
實例是否指向相同或不同的Java類?將鑄造jclass
返回到jobject
並調用java.lang.Object.hashcode
就會產生所需的結果?
更新:奇數,我可以調用hashcode()
成功,但它總是返回-1
。
更新2:this也不管用,我得到的全部是java.lang.Class
,無論我怎麼嘗試。
謝謝,現在我對JNI有了更多的瞭解!是的,我記得當ICS推出時,我的應用程序中出現了大量的JNI錯誤。一噸的樂趣,我已經將它們固定:) –
P. S.能否請您澄清兩個不同的對象都可以有相同的散列碼?我的意思是,你指的哈希值的概率性質和事實,即碰撞是不可能的,還是你的意思是,它實際上可以在真正的應用程序發生具有統計學顯著概率是多少? –
如果散列碼被計算(例如'java.lang.String'),兩個相等* *對象將總是具有相同的哈希值。對於簡單對象的哈希碼通常設置爲對象的32位地址,並「鎖定」第一次請求的東西它(所以如果對象移動它保持一致)。這避免了必須明確地將散列碼保存在永遠不會存儲在散列容器中的對象中。根據GC的特性,可能會在小範圍的地址中創建對象,從而造成碰撞的可能性。我不知道ART是如何工作的。 – fadden