Does `jobject` always have the same address if it represents the same Java instance?

196 Views Asked by At

Given a java object A a = new A(), and a bunch of native instance methods, if I were to take the address of the jobject representing a passed into those methods, would the address always be the same?

I have multiple final fields in these classes that I want to store in a hashmap in my C code (so I don't have to continue fetching them with Get___Field), with the hash of a jobject being the address. If I can guarantee that the address of a passed in jobject representing a will always be the same, then the hash is deterministic, which means my program's behavior will not be inconsistent.

1

There are 1 best solutions below

2
On BEST ANSWER

As comments have suggested, you cannot keep the passed-in jobject around beyond the current JNI call context because it is a local reference. The jobject values may be reused (leading to duplicate table entries) or become invalid. Furthermore, each call to CreateGlobalRef() will create a new, distinct jobject. The short answer is "you cannot do it this way". Such has been already addressed in this post. As an alternative approach, note that every Java Object has a hashCode() and equals() method. You can call those methods from your C/C++ code using JNI, and use them in your hash table. However, without knowing the details of when and how you are fetching the field values, calling JNI methods may not be any better than fetching the field values again.

Finally, as answered in this question, you can test jobject equality directly using env->IsSameObject(jobject1, jobject2). Presumably, jobject1 is the global reference that you have created and stored, whereas jobject2 is the passed-in local reference that you want to test against. Unfortunately this still doesn't help you probe into your hash table.