JNI中如何判断作为jobject的Class<?>引用是否匹配指定jclass
JNI判断Class<?>引用与指定jclass是否匹配的解决方案
直接比较指针失败的原因
- 代码第一步存在逻辑错误:
classRef本身就是Java层Class<?>类型的实例(对应你传入的类对象),调用GetObjectClass(env, classRef)得到的是**java.lang.Class这个类本身的元数据jclass**,和你要比较的目标类完全无关,这是比较失败的核心原因。 - 额外注意:JNI层的
jobject/jclass本质是Java对象的代理引用指针,同一个Java对象对应的不同类型(局部/全局/弱全局)、不同时机创建的JNI引用,指针值可能完全不同,直接用==比较地址没有任何意义。
正确方案1:严格判断是否为同一个类
直接用JNI标准提供的IsSameObject函数判断两个引用是否指向同一个Java对象即可,不需要额外获取类元:
// 直接比较两个Class对象是否为同一个 jboolean isSameClass = (*env)->IsSameObject(env, classRef, int_class); if (isSameClass == JNI_TRUE) { // 匹配成功的逻辑 }
正确方案2:判断继承/赋值兼容关系
如果不需要严格相等,而是要判断classRef代表的类是否可以赋值给int_class代表的类(等价Java代码int.class.isAssignableFrom(classRef)),可以调用JavaClass类的原生方法实现:
// 先获取Class类的isAssignableFrom方法ID jclass classClazz = (*env)->FindClass(env, "java/lang/Class"); jmethodID isAssignableFromMid = (*env)->GetMethodID(env, classClazz, "isAssignableFrom", "(Ljava/lang/Class;)Z"); // 调用方法判断兼容性 jboolean isAssignable = (*env)->CallBooleanMethod(env, int_class, isAssignableFromMid, classRef); if (isAssignable == JNI_TRUE) { // 兼容的逻辑 } // 用完记得释放局部引用避免内存泄漏 (*env)->DeleteLocalRef(env, classClazz);
内容的提问来源于stack exchange,提问作者Luke Hutchison
相关产品推荐
相关产品推荐

