zoukankan      html  css  js  c++  java
  • 访问JAVA中的字段(jfieldID)

    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

  • 相关阅读:
    小事引发的思考
    C++程序设计教程学习(0)-引子
    Cygwin安装
    PATHEXT环境变量简介
    Oracle Real Application Cluster
    SQLNET.AUTHENTICATION_SERVICES参数说明
    用神经网络拟合数据
    用PyTorch自动求导
    用PyTorch做参数估计
    深度学习基础(概念性)
  • 原文地址:https://www.cnblogs.com/lijunamneg/p/2829023.html
Copyright © 2011-2022 走看看