Java Native Interface Programming |
The JNI provides functions that native methods use to get and set Java fields. You can get and set both instance fields and static (class) fields. Similar to accessing Java methods, you use different JNI functions to access instance and static fields.
Our example program,
FieldAccess.java
, contains a class with one static integer fieldsi
and an instance string fields
. It 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 Java after returning from the native method.Procedure for Accessing a Java Field
To get and set Java fields from a native method, you must do the following:
Similar to calling a Java method, we factor out the cost of field lookup using a two-step process. 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 have:fid = (*env)->GetStaticFieldID(env, cls, "si", "I");and: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. Pass the class to the appropriate static field access functions. Pass the object to the appropriate instance field access functions. For example, in
FieldAccess.c
, we have:si = (*env)->GetStaticIntField(env, cls, fid);and: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 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 (c.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 previous section which summarizes the encoding for the Java type signatures and their matching Java types.
You can use
javap
with option "-s" to generate the field signatures from class files. For example, run:This gives you output containing:javap -s -p FieldAccess... static si I s Ljava/lang/String; ...
Java Native Interface Programming |