在我的C程序中,我有以下代码:
jclass class;
jmethodID method;
class = (*env)->FindClass(env, "java/lang/Short");
method = (*env)->GetMethodID(env, class, "<init>", "(S)V");
printf("First: class=%p * method=%p\n", class, method);
class = (*env)->FindClass(env, "java/lang/Short");
method = (*env)->GetMethodID(env, class, "<init>", "(S)V");
printf("Second: class=%p * method=%p\n", class, method);当我编译程序(用GCC语言)并运行它时,它提供了以下输出:
First: class=0x7f55ac089450 * method=0x7f55ac0d99b8
Second: class=0x7f55ac089458 * method=0x7f55ac0d99b8如您所见,每次调用FindClass时,类的地址是不同的。我认为这个类的地址是静态的,在我们的程序生命周期内它不会改变。事实上,当你从IBM读到这篇关于如何使用JNI (https://developer.ibm.com/languages/java/articles/j-jni/#notc)优化C代码的文章时,他们说要缓存FindClass返回的值(因此人们期望它不会改变)。但是,如果稍后在JNI函数调用中使用这个缓存的值,它将导致C程序崩溃(因为它使用的是Java类的错误地址)。
另一件奇怪的事情是,当缓存FindClass为类java/lang/Integer返回的值时(而不是上面发布的java/lang/Short ),然后在以后的每件事上使用这个缓存的值时,一切都会正常地正常工作(即不会崩溃)。
发布于 2021-02-19 18:17:52
FindClass返回的是本地参考,一个JavaClass对象。
在您的示例中,您将得到两个单独的引用--但它们都可能引用同一个对象。
考虑一下,如果行为符合您的预期,并且获得了两个FindClass调用的相同引用,那么会发生什么情况:
first = (*env)->FindClass(env, "java/lang/Short");
second = (*env)->FindClass(env, "java/lang/Short");
(*env)->DeleteLocalRef(env, first);
method = (*env)->GetMethodID(env, second, "<init>", "(S)V"); // OOPS! this reference may no longer be valid实际上,上面的内容会很好,因为first和second将是对Class<Short>的单独引用。
https://stackoverflow.com/questions/66281871
复制相似问题