FindClass-获取java类

32 阅读2分钟

FindClass 函数说明

FindClassJNIEnv 接口中一个重要的函数,用于在JNI环境中获取Java类的引用。

函数原型

jclass FindClass(JNIEnv *env, const char *name);

参数说明

  • JNIEnv *env: JNI环境指针
  • const char *name: Java类的全限定名(fully qualified name)

返回值

  • 成功时返回指向Java类的 jclass 引用
  • 失败时返回 NULL,并在JVM中抛出异常

类名格式

1. 基本类

// Java基本类
jclass stringClass = env->FindClass("java/lang/String");
jclass integerClass = env->FindClass("java/lang/Integer");
jclass arrayListClass = env->FindClass("java/util/ArrayList");

2. 自定义类

// 自定义类(包名用/分隔)
jclass myClass = env->FindClass("com/example/MyClass");
jclass calculatorClass = env->FindClass("Calculator");  // 默认包下的类

3. 数组类

// 数组类
jclass intArrayClass = env->FindClass("[I");        // int[]
jclass stringArrayClass = env->FindClass("[Ljava/lang/String;");  // String[]

使用示例

// 示例1:创建Java String对象
jclass stringClass = env->FindClass("java/lang/String");
jmethodID constructor = env->GetMethodID(stringClass, "<init>", "(Ljava/lang/String;)V");
jstring javaString = env->NewStringUTF("Hello World");
jobject newString = env->NewObject(stringClass, constructor, javaString);

// 示例2:使用自定义类
jclass calculatorClass = env->FindClass("CalculatorWithField");
jmethodID constructor = env->GetMethodID(calculatorClass, "<init>", "()V");
jobject calculatorObj = env->NewObject(calculatorClass, constructor);

// 示例3:检查类是否存在
jclass myClass = env->FindClass("com/example/NonExistentClass");
if (myClass == NULL) {
    // 类未找到,处理异常
    env->ExceptionDescribe();  // 打印异常信息
    env->ExceptionClear();     // 清除异常
    // 可以进行错误处理
}

注意事项

1. 类名分隔符

  • 使用正斜杠 / 而不是点 . 来分隔包名
  • 正确: "java/lang/String"
  • 错误: "java.lang.String"

2. 异常处理

jclass clazz = env->FindClass("NonExistentClass");
if (clazz == NULL) {
    // FindClass失败会自动抛出ClassNotFoundException
    // 需要处理异常或清理资源
    return;  // 或适当的错误处理
}

3. 局部引用

  • FindClass 返回的是局部引用,在当前native方法返回后会自动释放
  • 如需长期持有,需要使用 NewGlobalRef
jclass localClass = env->FindClass("java/lang/String");
jclass globalClass = (jclass)env->NewGlobalRef(localClass);
// 使用globalClass...
env->DeleteGlobalRef(globalClass);  // 使用完毕后记得删除全局引用

常见用途

  1. 创建Java对象实例
  2. 获取字段和方法ID
  3. 调用静态方法
  4. 类型检查和转换