当前位置: 首页 > news >正文

GetFieldID函数介绍

GetFieldIDJNIEnv 接口中用于获取Java类实例字段ID的重要函数。

函数原型

jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

参数说明

  • JNIEnv *env: JNI环境指针
  • jclass clazz: Java类的引用
  • const char *name: 字段名称
  • const char *sig: 字段签名(类型描述符)

返回值

  • 成功时返回字段ID (jfieldID)
  • 失败时返回 NULL,并在JVM中抛出异常

字段签名规则

基本类型签名
Java类型签名
booleanZ
byteB
charC
shortS
intI
longJ
floatF
doubleD
voidV
引用类型签名
  • 对象类型: L完整类名; (注意结尾的分号)
    • Ljava/lang/String; (String)
    • Lcom/example/MyClass; (自定义类)
  • 数组类型: [ + 元素类型签名
    • [I (int[])
    • [Ljava/lang/String; (String[])

使用示例

1. 访问基本类型字段
// Java代码
public class Calculator {private int result;private boolean isActive;private double value;
}// JNI代码
jclass clazz = env->GetObjectClass(obj);
jfieldID resultFieldID = env->GetFieldID(clazz, "result", "I");      // int类型
jfieldID activeFieldID = env->GetFieldID(clazz, "isActive", "Z");    // boolean类型
jfieldID valueFieldID = env->GetFieldID(clazz, "value", "D");        // double类型
2. 访问对象类型字段
// Java代码
public class Person {private String name;private Date birthDate;
}// JNI代码
jclass clazz = env->GetObjectClass(obj);
jfieldID nameFieldID = env->GetFieldID(clazz, "name", "Ljava/lang/String;");  // String类型
jfieldID dateFieldID = env->GetFieldID(clazz, "birthDate", "Ljava/util/Date;"); // Date类型
3. 访问数组类型字段
// Java代码
public class DataContainer {private int[] numbers;private String[] names;
}// JNI代码
jclass clazz = env->GetObjectClass(obj);
jfieldID numbersFieldID = env->GetFieldID(clazz, "numbers", "[I");  // int[]类型
jfieldID namesFieldID = env->GetFieldID(clazz, "names", "[Ljava/lang/String;"); // String[]类型

完整使用示例

// Java类
public class Student {private String name;private int age;private double[] scores;// getters and setters...
}// JNI函数实现
JNIEXPORT void JNICALL Java_MyClass_updateStudent(JNIEnv *env, jobject obj, jobject studentObj, jstring newName, jint newAge) {// 获取Student类jclass studentClass = env->GetObjectClass(studentObj);// 获取字段IDjfieldID nameFieldID = env->GetFieldID(studentClass, "name", "Ljava/lang/String;");jfieldID ageFieldID = env->GetFieldID(studentClass, "age", "I");jfieldID scoresFieldID = env->GetFieldID(studentClass, "scores", "[D");// 检查字段是否存在if (nameFieldID == NULL || ageFieldID == NULL || scoresFieldID == NULL) {// 字段不存在,处理异常env->ExceptionDescribe();return;}// 设置字段值env->SetObjectField(studentObj, nameFieldID, newName);env->SetIntField(studentObj, ageFieldID, newAge);// 创建新的double数组并设置jdoubleArray newScores = env->NewDoubleArray(3);jdouble scores[] = {95.5, 87.0, 92.5};// 设置数组元素,参数依次为:数组对象,起始位置,长度,源数组env->SetDoubleArrayRegion(newScores, 0, 3, scores);env->SetObjectField(studentObj, scoresFieldID, newScores);
}

注意事项

1. 异常处理
jfieldID fieldID = env->GetFieldID(clazz, "fieldName", "I");
if (fieldID == NULL) {// 字段不存在或签名错误env->ExceptionDescribe();  // 打印异常信息env->ExceptionClear();     // 清除异常return;  // 适当的错误处理
}
// GetObjectField 使用 jint value = env->GetIntField(obj, fieldID);
return value;
2. 字段访问权限
  • GetFieldID 可以获取 private、protected、public 字段的ID
  • 但实际访问时仍需遵循Java访问控制规则
3. 性能考虑
// 推荐:缓存字段ID以提高性能
static jfieldID resultFieldID = NULL;
if (resultFieldID == NULL) {jclass clazz = env->GetObjectClass(obj);resultFieldID = env->GetFieldID(clazz, "result", "I");// 可能需要创建全局引用以长期持有
}

相关函数对比

函数用途字段类型
GetFieldID获取实例字段ID实例字段
GetStaticFieldID获取静态字段ID静态字段
GetFieldID + GetObjectField读取对象字段对象引用
GetFieldID + GetIntField读取int字段基本类型

GetFieldID 是JNI中访问Java对象字段的关键函数,正确使用它能够实现C++代码与Java对象状态的交互。

http://www.dtcms.com/a/556764.html

相关文章:

  • 二分查找为什么总是写错
  • PPO算法:从深度学习视角入门强化学习
  • 《数据结构风云》递归算法:二叉树遍历的精髓实现
  • 广州网站建设学习郑州官网seo推广
  • 进程控制(创建、终止)
  • 做网站的上海公司有哪些运营网站团队建设
  • 深入HBase:原理剖析与优化实战
  • 北京城市雕塑建设管理办公室网站电商网络运营
  • 【Centos】服务器硬盘扩容之新加硬盘扩容到现有路径下
  • 一.docker基础概念
  • 【Linux系统编程】进程概念(一)冯诺依曼体系结构、操作系统
  • RabbitMQ简介
  • Hudi、Iceberg、Delta Lake、Paimon 建表语法与场景示例
  • C++ 继承:从概念到实战
  • AI驱动的智能运维知识平台建设:技术实践与未来展望
  • XCP标准文档PART2协议层
  • 基于深度学习的中国交通警察手势识别与指令优先级判定系统
  • 专业微网站建设公司哪家好可以访问的国外网站
  • 配置(5):Nginx的删除与卸载
  • Tableau 从零到精通:系统教学文档(自学版)
  • 孤能子视角:“他来了“与“他怎么来了“
  • 【xx】PCIe协议 之 Margning篇 之 Serdes PHY 验证实战举例
  • 【SpringAI入门】初识SpringAI
  • 关于“灵犀”的争议(三)
  • 网站收录是什么意思?机关网站建设存在的问题
  • 单词接龙----图论
  • c++ pugixml封装使用示例
  • Appium和Detox,哪一种更好的为手机自动化
  • 山东网站开发工作室百度一下马上知道
  • Maven 从入门到实战:搞定依赖管理与 Spring Boot 项目构建