Java Native Interface Programming |
The JNI provides functions that native methods use to get and set Java programming language fields. You can get and set both instance fields and static (class) fields. Similar to accessing methods, you use one set of JNI functions to access instance fields and another set of JNI functions to access static fields.
Our example program,
FieldAccess.java
, contains a class with one static integer fieldsi
and an instance string fields
. The example program calls the native methodaccessFields
, which prints out the value of these two fields and then sets the fields to new values. To verify the fields have indeed changed, we print out their values again in the Java application after returning from the native method.Procedure for Accessing a Java Programming Language Field
To get and set Java programming language fields from a native language method, you must do the following:
Just as we did when calling a Java programming language method, we factor out the cost of field lookup using a two-step process. First we obtain the field ID, then use the field ID to access the field itself. The field ID uniquely identifies a field in a given class. Similar to method IDs, a field ID remains valid until the class from which it is derived is unloaded.
- Obtain the identifier for that field from its class, name, and type signature. For example, in
FieldAccess.c
, we get the identifier for the static integer fieldsi
, as follows:fid = (*env)->GetStaticFieldID(env, cls, "si", "I");and we get the identifier for the instance string fields
, as follows:fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");- Use one of several JNI functions to either get or set the field specified by the field identifier. To get the value of a static field, pass the class to one of the appropriate static field access functions. To get the value of an instance field, pass the object to the appropriate instance field access function. For example, in
FieldAccess.c
, we useGetStaticIntField
to get the value of the static integer fieldsi
, as follows:si = (*env)->GetStaticIntField(env, cls, fid);We use the functionGetObjectField
to get the value of the instance string fields
:jstr = (*env)->GetObjectField(env, obj, fid);Field Signatures
Field signatures are specified following the same encoding scheme as method signatures. The general form of a field signature is:
"field type"The field signature is the encoded symbol for the type of the field, enclosed in double quotes (""). The field symbols are the same as the argument symbols in the method signature. That is, you represent an integer field with "I", a float field with "F", a double field with "D", a boolean field with "Z", and so on.
The signature for a Java programming language object, such as a
String
, begins with the letter L, followed by the fully-qualified class for the object, and terminated by a semicolon (;). Thus, you form the field signature for aString
variable, such asc.s
in FieldAccess.java, as follows:"Ljava/lang/String;"Arrays are indicated by a leading square bracket ([) followed by the type of the array. For example, you designate an integer array as follows:
"[I"Refer to the table in the previous section that summarizes the encoding for the Java programming language type signatures and their matching Java programming language types.
You can use
javap
with option "-s" to generate the field signatures from class files. For example, run:This gives you output containing the following two field signatures:javap -s -p FieldAccess... static si I s Ljava/lang/String; ...
Java Native Interface Programming |