访问JAVA中的字段(jfieldID)

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

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

复制代码

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 等用来访问基本类型字段的函数。spa


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

 

 

访问静态字段
访问静态字段和访问实例字段类似,看下面这个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 的实现:ip

复制代码

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字符串

相关文章
相关标签/搜索