The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Java Native Interface
Lesson: Interacting with Java from the Native Side

## Accessing Java Member Variables

> The JNI provides functions that native methods use to get and set Java member variables. You can get and set both instance and class member variables. Similar to accessing methods, you use one set of JNI functions to access instance member variables and another set of JNI functions to access class member variables.

> Our example program, `FieldAccess.java`, contains a class with one class integer member variable `si` and an instance string member variable `s`. The example program calls the native method `accessFields`, which prints out the value of these two member variables and then sets the member variables to new values. To verify the member variables have indeed changed, we print out their values again in the Java application after returning from the native method.

### Procedure for Accessing a Java Member Variable

To get and set Java member variables from a native language method, you must do the following:

- Obtain the identifier for that member variable from its class, name, and type signature. For example, in `FieldAccess.c`, we get the identifier for the class integer member variable `si` as follows:

  >       fid = (*env)->GetStaticFieldID(env, cls, "si", "I");

  and we get the identifier for the instance string member variable `s` as follows:

  >       fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");

- Use one of several JNI functions to either get or set the member variable specified by the member variable identifier. To get the value of a class member variable, pass the class to one of the appropriate class member variable access functions. To get the value of an instance member variable, pass the object to the appropriate instance member variable access function. For example, in `FieldAccess.c`, we use `GetStaticIntField` to get the value of the class integer member variable `si`, as follows:

  >       si = (*env)->GetStaticIntField(env, cls, fid);

  We use the function `GetObjectField` to get the value of the instance string member variable `s`:

  >       jstr = (*env)->GetObjectField(env, obj, fid);

Just as we did when calling a Java method, we factor out the cost of member variable lookup using a two-step process. First we obtain the member variable ID, then use the member variable ID to access the member variable itself. The member variable ID uniquely identifies a member variable in a given class. Similar to method IDs, a member variable ID remains valid until the class from which it is derived is unloaded.

### Member Variable Signatures

Specify member variable signatures following the same encoding scheme as method signatures. The general form of a member variable signature is:

>     "member variable type"

The member variable signature is the encoded symbol for the type of the member variable, enclosed in double quotes (""). The member variable symbols are the same as the argument symbols in the method signature. That is, you represent an integer member variable with "I", a float member variable with "F", a double member variable with "D", a boolean member variable 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 member variable signature for a `String` variable, such as `c.s` in `FieldAccess.java`, as follows:

>     "Ljava/lang/String;"

To indicate an array, use 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 type signatures and their matching Java types.

You can use the Java class disassembler tool `javap` with option "-s" to generate the member variable signatures from class files. For example, run:

>     javap -s -p FieldAccess

This gives you output containing the following two member variable signatures:

>     ...
>     static si I
>     s Ljava/lang/String;
>     ...

| Start of Tutorial > Start of Trail > Start of Lesson | Search