field in java_访问JAVA中的字段(jfieldID)

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

访问对象字段:

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

classInstanceFieldAccess {privateString s;private native voidaccessField();public static voidmain(String args[]) {

InstanceFieldAccess c= newInstanceFieldAccess();

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 例子的变形:

classStaticFielcdAccess {private static intsi;private native voidaccessField();public static voidmain(String args[]) {

StaticFieldAccess c= newStaticFieldAccess();

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值