當前位置:才華齋>計算機>java語言>

java中什麼是欄位

java語言 閱讀(2.69W)

我們把表中的每一行叫做一個“記錄”,每一個記錄包含這行中的所有資訊,就像在通訊錄資料庫中某個人全部的資訊,但記錄在資料庫中並沒有專門的記錄名,常常用它所在的行數表示這是第幾個記錄。在資料庫中存放在錶行列交叉處的資料叫做“值”,它是資料庫中最基本的儲存單元,它的位置要由這個表中的記錄和欄位來定義。

java中什麼是欄位

JAVA支援兩種field(欄位),每一個物件的例項都有一個物件欄位的複製;所有的物件共享一個類的靜態欄位。本地方法使用JNI提供的函式可以獲取和修改這兩種欄位。先看一個從本地程式碼中訪問物件欄位的例子:

class InstanceFieldAccess {

private String s;

private native void accessField();

public static void main(String args[]) {

InstanceFieldAccess c = new InstanceFieldAccess();

c.s = "abc";

ssField();

tln("In Java:");

tln(" c.s = "" + c.s + """);

}

static {

Library("InstanceFieldAccess");

}

}

InstanceFieldAccess這個類定義了一個物件欄位s。main方法建立了一個物件並設定s的值,然後呼叫本地方法ssField在原生代碼中列印s的值,並把它修改為一個新值。本地方法返回後,JAVA中把這個值再列印一次,可以看出來,欄位s的值已經被改變了。下面是本地方法的實現:

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:");

/* 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"", 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"

4.1.1 訪問一個物件欄位的流程

為了訪問一個物件的例項欄位,本地方法需要做兩步:

首先,通過在類引用上呼叫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等用來訪問基本型別欄位的函式。

4.1.2 欄位描述符

在上一節我們使用過一個特殊的C字串“Ljava/lang/String”來代表一個JVM中的欄位型別。這個字串被稱為JNI field descriptor(欄位描述符)。

字串的內容由欄位被宣告的型別決定。例如,使用“I”來表示一個int型別的欄位,“F”來表示一個float型別的欄位,“D”來表示一個double型別的欄位,“Z”來表示一個boolean型別的欄位等等。

像ng這樣的引用型別的描述符都是以L開頭,後面跟著一個JNI類描述符,以分號結尾。一個JAVA類的全名中的包名分隔符“.”被轉化成“/”。因此,對於一個欄位型別的欄位來說,它的描述符是“Ljava/lang/String”。

陣列的描述符中包含“]”字元,後面會跟著陣列型別的描述符,如“[I”是int[]型別的欄位的描述符。12.3.3詳細介紹了各種型別的欄位描述以及他們代表的JAVA型別。

你可以使用javap工具來生成欄位描述符。

4.1.3 訪問靜態欄位

訪問靜態欄位和訪問例項欄位相似,看下面這個InstanceFieldAccess例子的變形:

class StaticFielcdAccess {

private static int si;

private native void accessField();

public static void main(String args[]) {

StaticFieldAccess c = new StaticFieldAccess();

= 100;

ssField();

tln("In Java:");

tln(" = " + si);

}

static {

Library("StaticFieldAccess");

}

}

StaticFieldAccess這個類包含一個靜態欄位si,main方法建立了一個物件,初始化靜態欄位,然後呼叫本地方法ssField在原生代碼中列印靜態欄位中的值,然後設定新的值,為了演示這個值確實被改變了,在本地方法返回後,JAVA中再次這個靜態欄位的值。

下面是本地方法ssField的實現:

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:");

/* 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(" = %d", si);

(*env)->SetStaticIntField(env, cls, fid, 200);

}

執行程式可得到輸出結果:

In C:

= 100

In Java:

= 200