如果'jobject'代表相同的Java实例,它是否总是具有相同的地址?

如果'jobject'代表相同的Java实例,它是否总是具有相同的地址?,java,c,java-native-interface,native,jniwrapper,Java,C,Java Native Interface,Native,Jniwrapper,给定一个java对象a=new a(),以及一组本机实例方法,如果我将表示a的jobject的地址传递到这些方法中,地址是否总是相同的? 在这些类中,我有多个最终字段,我想将它们存储在我的C代码中的hashmap中(因此我不必继续使用Get_uuuuufield获取它们),而jobject的散列就是地址。如果我可以保证传入的表示a的jobject的地址总是相同的,那么散列是确定的,这意味着我的程序的行为不会不一致。如注释所示,您不能将传入的jobject保留在当前JNI调用上下文之外,因为它是本

给定一个java对象
a=new a()
,以及一组本机实例方法,如果我将表示
a
jobject的地址传递到这些方法中,地址是否总是相同的?


在这些类中,我有多个最终字段,我想将它们存储在我的C代码中的hashmap中(因此我不必继续使用
Get_uuuuufield
获取它们),而
jobject
的散列就是地址。如果我可以保证传入的表示
a
jobject
的地址总是相同的,那么散列是确定的,这意味着我的程序的行为不会不一致。

如注释所示,您不能将传入的
jobject
保留在当前JNI调用上下文之外,因为它是本地引用。
jobject
值可能被重用(导致重复的表条目)或变得无效。此外,每次调用
CreateGlobalRef()
都将创建一个新的、不同的
jobject
。简单的回答是“你不能这样做”。这一问题已在本报告中得到解决。作为替代方法,请注意每个Java对象都有一个
hashCode()
equals()
方法。您可以使用JNI从C/C++代码中调用这些方法,并在哈希表中使用它们。但是,在不知道何时以及如何获取字段值的详细信息的情况下,调用JNI方法可能不会比再次获取字段值更好


最后,如中所述,您可以直接使用
env->IsSameObject(jobject1,jobject2)
测试
jobject
是否相等。大概,
jobject1
是您创建和存储的全局引用,而
jobject2
是您要测试的传入本地引用。不幸的是,这仍然不能帮助您探查哈希表。

如果您希望在多个jni调用中保留对任何对象的引用,则需要调用NewGlobalRef。但是,尽管这保证了您持有的引用仍然有效,但我不知道它是否保证传入的后续引用将匹配。@prl我已经查看过了,但是调用
NewGlobalRef
会提供一个可以分配给全局变量的全局引用,传入的
jobject
是全局的还是本地的似乎没有改变。根据我目前的理解,传入的
jobject
不是我构造和确定的对象,JVM构造并传入它。在类似的情况下,我在对象中存储了一个“对象id”(散列)。我让Java传入id作为本机方法的附加参数。@prl如果我选择传入附加参数,我还可以传入最终实例字段的值(并在C代码中放弃全局hashmap的想法),这会比通过JNI接口获取C代码中的值更有效吗?@prl如果我创建了一个静态本机方法(将代替构造函数使用),该方法返回对
jobject
(表示java实例)的全局引用,您知道我在本机实例方法中接收的所有其他
jobject
是否与此全局引用等效吗?如果我创建了一个返回全局
jobject
的静态本机工厂方法,该对象是否仍不会传递到实例本机方法中?我不这么认为。从java传递到C/C++的任何内容都将获得一个全新的本地引用。