性能问答>为什么 JNI 的 FindClass 方法有奇怪的副作用?>
2回复

为什么 JNI 的 FindClass 方法有奇怪的副作用?



我在用 JNI 的时候遇到了一个很奇怪的问题,有人能帮忙分析一下到底是怎么回事吗

如果我按原样运行下面的代码,会看到这个:

(a) 7fb6f022faf0 7fb6f022fb00 0
(b) 7fb6f022faf8 7fb6f022fb00 1

如果我取消注释标记为 // (*) 的行,那么我会看到:

(a) 7f6ce822faf0 7f6ce822fb08 1
(b) 7f6ce822fb00 7f6ce822fb08 1

注释掉 (*) 行(应该是空操作!)后,用 Class.equals 方法发现 Integer.class 的一个实例与 Integer.class 的另一个实例不相等。 取消注释该行,java.lang.Integer 在 test1 方法中被查找了两次而不是一次,并且由于某种原因,现在发现 Integer.class 的两个实例是相等的! (这是在 JDK 16 上。)

完全搞不懂这是怎么回事

pkg/Test.java:

package pkg;
public class Test {
    public static native void test0();
    public static native void test1(Object... args);

    public static void main(String[] args) throws Exception {
        test0();
        test1(7);
    }
}

test.c:

#include <jni.h>
#include <stdio.h>

jclass Integer_class_0;

JNIEXPORT void JNICALL Java_pkg_Test_test0(JNIEnv *env, jclass ignored) {
    Integer_class_0 = (*env)->FindClass(env, "java/lang/Integer");
}

JNIEXPORT void JNICALL Java_pkg_Test_test1(JNIEnv *env, jclass ignored, 
            jobjectArray args) {
    //(*env)->FindClass(env, "java/lang/Integer");    // (*)
    jobject arg = (*env)->GetObjectArrayElement(env, args, 0);
    jclass arg_type = (*env)->GetObjectClass(env, arg);
    jclass Integer_class_1 = (*env)->FindClass(env, "java/lang/Integer");

    jclass cls_class = (*env)->FindClass(env, "java/lang/Class");
    jmethodID cls_equals_methodID =
            (*env)->GetMethodID(env, cls_class, "equals", "(Ljava/lang/Object;)Z");

    printf("(a) %lx %lx %d\n", Integer_class_0, Integer_class_1,
            (*env)->CallBooleanMethod(env,
                    Integer_class_0, cls_equals_methodID, Integer_class_1));
    printf("(b) %lx %lx %d\n", arg_type, Integer_class_1,
            (*env)->CallBooleanMethod(env,
                    arg_type, cls_equals_methodID, Integer_class_1));
}
1082 阅读
请先登录,查看2条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步