- 相關(guān)推薦
java中什么是字段
我們把表中的每一行叫做一個(gè)“記錄”,每一個(gè)記錄包含這行中的所有信息,就像在通訊錄數(shù)據(jù)庫(kù)中某個(gè)人全部的信息,但記錄在數(shù)據(jù)庫(kù)中并沒(méi)有專(zhuān)門(mén)的記錄名,常常用它所在的行數(shù)表示這是第幾個(gè)記錄。在數(shù)據(jù)庫(kù)中存放在表行列交叉處的數(shù)據(jù)叫做“值”,它是數(shù)據(jù)庫(kù)中最基本的存儲(chǔ)單元,它的位置要由這個(gè)表中的記錄和字段來(lái)定義。
JAVA支持兩種field(字段),每一個(gè)對(duì)象的實(shí)例都有一個(gè)對(duì)象字段的復(fù)制;所有的對(duì)象共享一個(gè)類(lèi)的靜態(tài)字段。本地方法使用JNI提供的函數(shù)可以獲取和修改這兩種字段。先看一個(gè)從本地代碼中訪問(wèn)對(duì)象字段的例子:
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");
}
}
InstanceFieldAccess這個(gè)類(lèi)定義了一個(gè)對(duì)象字段s。main方法創(chuàng)建了一個(gè)對(duì)象并設(shè)置s的值,然后調(diào)用本地方法InstanceFieldAccess.accessField在本地代碼中打印s的值,并把它修改為一個(gè)新值。本地方法返回后,JAVA中把這個(gè)值再打印一次,可以看出來(lái),字段s的值已經(jīng)被改變了。下面是本地方法的實(shí)現(xiàn):
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);
}
運(yùn)行程序,得到輸出為:
In C:
c.s = "abc"
In Java:
c.s = "123"
4.1.1 訪問(wèn)一個(gè)對(duì)象字段的流程
為了訪問(wèn)一個(gè)對(duì)象的實(shí)例字段,本地方法需要做兩步:
首先,通過(guò)在類(lèi)引用上調(diào)用GetFieldID獲取field ID(字段ID)、字段名字和字段描述符:
Fid=(*env)->GetFieldID(env,cls,”s”,”Ljava/lang/String;”);
上例中的代碼通過(guò)在對(duì)象引用obj上調(diào)用GetObjectClass獲取到類(lèi)引用。一旦獲取到字段ID,你就可以把對(duì)象和字段ID作為參數(shù)來(lái)訪問(wèn)字段:
Jstr=(*env)->GetObjectField(env,obj,fid);
因?yàn)樽址蛿?shù)組是特殊的對(duì)象,所以我們使用GetObjectField來(lái)訪問(wèn)字符串類(lèi)型的實(shí)例字段。除了Get/SetObjectField,JNI還支持其它如GetIntField、SetFloatField等用來(lái)訪問(wèn)基本類(lèi)型字段的函數(shù)。
4.1.2 字段描述符
在上一節(jié)我們使用過(guò)一個(gè)特殊的C字符串“Ljava/lang/String”來(lái)代表一個(gè)JVM中的字段類(lèi)型。這個(gè)字符串被稱(chēng)為JNI field descriptor(字段描述符)。
字符串的內(nèi)容由字段被聲明的類(lèi)型決定。例如,使用“I”來(lái)表示一個(gè)int類(lèi)型的字段,“F”來(lái)表示一個(gè)float類(lèi)型的字段,“D”來(lái)表示一個(gè)double類(lèi)型的字段,“Z”來(lái)表示一個(gè)boolean類(lèi)型的字段等等。
像java.lang.String這樣的引用類(lèi)型的描述符都是以L開(kāi)頭,后面跟著一個(gè)JNI類(lèi)描述符,以分號(hào)結(jié)尾。一個(gè)JAVA類(lèi)的全名中的包名分隔符“.”被轉(zhuǎn)化成“/”。因此,對(duì)于一個(gè)字段類(lèi)型的字段來(lái)說(shuō),它的描述符是“Ljava/lang/String”。
數(shù)組的描述符中包含“]”字符,后面會(huì)跟著數(shù)組類(lèi)型的描述符,如“[I”是int[]類(lèi)型的字段的描述符。12.3.3詳細(xì)介紹了各種類(lèi)型的字段描述以及他們代表的JAVA類(lèi)型。
你可以使用javap工具來(lái)生成字段描述符。
4.1.3 訪問(wèn)靜態(tài)字段
訪問(wèn)靜態(tài)字段和訪問(wèn)實(shí)例字段相似,看下面這個(gè)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這個(gè)類(lèi)包含一個(gè)靜態(tài)字段si,main方法創(chuàng)建了一個(gè)對(duì)象,初始化靜態(tài)字段,然后調(diào)用本地方法StaticFieldAccess.accessField在本地代碼中打印靜態(tài)字段中的值,然后設(shè)置新的值,為了演示這個(gè)值確實(shí)被改變了,在本地方法返回后,JAVA中再次這個(gè)靜態(tài)字段的值。
下面是本地方法StaticFieldAccess.accessField的實(shí)現(xiàn):
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(" StaticFieldAccess.si = %d ", si);
(*env)->SetStaticIntField(env, cls, fid, 200);
}
運(yùn)行程序可得到輸出結(jié)果:
In C:
StaticFieldAccess.si = 100
In Java:
StaticFieldAccess.si = 200
【java中什么是字段】相關(guān)文章:
Java中的String為什么是不可變的07-10
什么是Java02-15
JAVA中throws和throw有什么區(qū)別04-28
Java與Java web有什么不同04-16
Java是什么07-03
java中反射機(jī)制05-26
Java中的clone方法08-15
JAVA中的main函數(shù)03-14
Java中finally的問(wèn)題05-30