文档章节

访问JAVA中的字段(jfieldID)

zhangyujsj
 zhangyujsj
发布于 2015/08/23 21:02
字数 660
阅读 23
收藏 0

JAVA 支持两种 field(字段),每一个对象的实例都有一个对象字段的复制;所有的对象共享一个类的静态字段。

访问对象字段
先看一个从本地代码中访问对象字段的例子:

复制代码

class InstanceFieldAccess { 
     private String s; 
  
     private native void accessField(); 
     public static void main(String args[]) { 
         InstanceFieldAccess c = new InstanceFieldAccess(); 
         c.s = "abc"; 
         c.accessField(); 
         System.out.println("In Java:"); 
         System.out.println("  c.s = \"" + c.s + "\""); 
     } 
     static { 
         System.loadLibrary("InstanceFieldAccess"); 
     } 
 }

复制代码

下面是本地方法的实现:

复制代码

JNIEXPORT void JNICALL  Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj) 
 { 
     jfieldID fid;   /* store the field ID */ 
     jstring jstr; 
     const char *str; 
  
     /* Get a reference to obj's class */ 
     jclass cls = (*env)->GetObjectClass(env, obj); //第一步
     printf("In C:\n"); 
  
     /* Look for the instance field s in cls */ 
     fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); //第二步
     if (fid == NULL) { 
         return; /* failed to find the field */ 
     } 
     
     /* Read the instance field s */ 
     jstr = (*env)->GetObjectField(env, obj, fid); //第三步
     str = (*env)->GetStringUTFChars(env, jstr, NULL); 
     if (str == NULL) { 
         return; /* out of memory */ 
     } 
     printf("  c.s = \"%s\"\n", str); 
     (*env)->ReleaseStringUTFChars(env, jstr, str); 
  
     /* Create a new string and overwrite the instance field */ 
     jstr = (*env)->NewStringUTF(env, "123"); 
     if (jstr == NULL) { 
         return; /* out of memory */ 
     } 
     (*env)->SetObjectField(env, obj, fid, jstr); 
}

复制代码

运行程序,得到输出为:
In C:
   c.s = "abc"
 In Java:
   c.s = "123"
  
访问一个对象字段的流程
为了访问一个对象的实例字段,本地方法需要做两步:
首先,通过在类引用上调用 GetFieldID 获取 field ID(字段ID)、字段名字和字段描述符:
Fid=(*env)->GetFieldID(env,cls,”s”,”Ljava/lang/String;”);
上例中的代码通过在对象引用obj上调用GetObjectClass获取到类引用。一旦获取到字段ID,
你就可以把对象和字段 ID作为参数来访问字段:
Jstr=(*env)->GetObjectField(env,obj,fid);
因为字符串和数组是特殊的对象,所以我们使用GetObjectField 来访问字符串类型的实例字段。
除了 Get/SetObjectField,JNI 还支持其它如 GetIntField、SetFloatField 等用来访问基本类型字段的函数。


Ljava/lang/String这个字符串被称为JNI field descriptor(字段描述符)。
字符串的内容由字段被声明的类型决定

 

 

访问静态字段
访问静态字段和访问实例字段相似,看下面这个InstanceFieldAccess 例子的变形:

复制代码

class StaticFielcdAccess { 
     private static int si; 
  
     private native void accessField(); 
     public static void main(String args[]) { 
         StaticFieldAccess c = new StaticFieldAccess(); 
         StaticFieldAccess.si = 100; 
         c.accessField(); 
         System.out.println("In Java:"); 
         System.out.println("  StaticFieldAccess.si = " + si); 
     } 
     static { 
         System.loadLibrary("StaticFieldAccess"); 
     } 
}

复制代码

下面是本地方法StaticFieldAccess.accessField 的实现:

复制代码

JNIEXPORT void JNICALL  Java_StaticFieldAccess_accessField(JNIEnv *env, jobject obj) 
 { 
     jfieldID fid;   /* store the field ID */ 
     jint si; 
  
     /* Get a reference to obj's class */ 
     jclass cls = (*env)->GetObjectClass(env, obj); 
  
     printf("In C:\n"); 
  
     /* Look for the static field si in cls */ 
     fid = (*env)->GetStaticFieldID(env, cls, "si", "I"); 
     if (fid == NULL) { 
         return; /* field not found */ 
     } 
 
    /* Access the static field si */ 

     si = (*env)->GetStaticIntField(env, cls, fid); 
     printf("  StaticFieldAccess.si = %d\n", si); 
     (*env)->SetStaticIntField(env, cls, fid, 200); 
 }

复制代码

运行程序可得到输出结果:
In C:
   StaticFieldAccess.si = 100
 In Java:
   StaticFieldAccess.si = 200


本文转载自:http://www.cnblogs.com/lijunamneg/archive/2012/12/22/2829023.html

zhangyujsj
粉丝 24
博文 358
码字总数 224241
作品 0
广州
私信 提问
Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释

上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: [cpp] view plai...

zhangyujsj
2015/08/23
36
0
ANDROID JNI之JAVA域与c域的互操作

本文讲述AndroidJava域与C域互操作:Java域调用c域的函数;c域访问Java域的属性和方法;c域生成的对象的保存与使用。重点讲解c域如何访问Java域。 虽然AndroidJNI实现中,c实现与c++实现是有...

垂盆草
2012/10/13
457
0
Android JNI开发系列(十)JNI访问 Java 实例变量和静态变量

JNI访问 Java 实例变量和静态变量 Java 中的实例变量和静态变量,在本地代码中如何来访问和修改。静态变量也称为类变量(属性),在所有实例对象中共享同一份数据,可以直接通过类名.变量名来...

蔡小鹏
2018/10/16
597
0
如何在C/C++中调用Java

转的一篇文章,看的不懂,先坐下记录吧~~~ java跨平台的特性使Java越来越受开发人员的欢迎,但也往往会听到不少的抱怨:用Java开发的图形用户窗口界面每次在启动的时候都会跳出一个控制台窗口...

claireyu
2011/10/09
312
5
JNI学习积累之三 ---- 操作JNI函数以及复杂对象传递

在掌握了JNI函数的使用和相关类型的映射后,以及知晓何利用javah工具生成对应的jni函数以及如何生成动态 链接库 (windos下就是.dll库,Linux就是.so库了,不懂在Window下生成dll动态库的,具...

天王盖地虎626
01/22
83
0

没有更多内容

加载失败,请刷新页面

加载更多

消息中间件——RabbitMQ的高级特性

前言 前面我们介绍了RabbitMQ的安装、各大消息中间件的对比、AMQP核心概念、管控台的使用、快速入门RabbitMQ。本章将介绍RabbitMQ的高级特性。分两篇(上/下)进行介绍。 消息如何保障100%的...

Java架构师ya七
55分钟前
9
0
如何编写高质量的 JS 函数(1) -- 敲山震虎篇

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ 作者:杨昆 一千个读者,有一千个哈姆雷特。 此系列文章将会从函数的执行机制、鲁棒性、函...

vivo互联网技术
今天
7
0
学会这5个Excel技巧,让你拒绝加班

在网上,随处都可以看到Excel技巧,估计已看腻了吧?但下面5个Excel技巧会让你相见恨晚。关键的是它们个个还很实用 图一 技巧1:快速删除边框 有时当我们处理数据需要去掉边框,按Ctrl+Shif...

干货趣分享
今天
11
0
JS基础-该如何理解原型、原型链?

JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个...

OBKoro1
今天
11
0
高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部