## Acceder a Campos Java

El JNI proporciona funciones que los métodos nativos utilizan para obtener y seleccionar campos Java. Se pueden obtener y seleccionar tanto campos de ejemplar como campos de clase (estáticos). Similarmente al acceso a los métodos, se utiliza un conjunto de funciones JNI para acceder a campos de ejemplar y otro conjunto para acceder a campos estáticos.

Nuestro programa de ejemplo, FieldAccess.java, contiene una clase con un campo Integer estático si y un campo String de ejemplar s. El programa de ejemplo llama al método nativo accessFields, que imprime los valores de esos dos campos y modifica esos valores. Para verificar que se han modificado realmente los valores de los campos, imprimimos de nuevo sus valores desde la aplicación Java después de que haya retornado el método nativo.

#### Procedimiento para Acceder a Campos Java

Para obtener y seleccionar campos Java desde un método nativo, se debe hacer lo siguiente:

- Obtener el idendificador para ese campo dentro de su clase, el nombre y el tipo de firma, Por ejemplo, en FieldAccess.c, obtenemos el identificador para el campo estático entero si de esta forma:

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

  y obtenemos el identificador para el campo string de ejemplar s, de esta forma:

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

- Utilizar una de las varias funciones JNI para obtener o modificar el campo especificado por el identificador del campo. Para obtener el valor del campo, se pasa la clase a una de las funciones de acceso a campos apropiada. Por ejemplo, en FieldAccess.c, utilizamos GetStaticIntField para obtener el valor del campo estático Intenger si, de esta forma:

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

  Utilizamos la función GetObjectField para obtener el valor del campo de ejemplar String s:

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

Igual que hicimos cuando llamamos a un método Java, dividimos el costo de la búsqueda del campo utilizando un proceso de dos pasos. Primero obtenemos el ID del campo, luego utilizamos el ID del campo para acceder al propio campo. El ID de campo sólo identifica a un campo en una clase dada. Igualmente que los IDs de método, un ID de campo permanece válido hasta que la clase de la que se ha derivado es descargada.

#### Firmas de Campos

Las firmas de campo se especifican siguiendo el mismo esquema de codificación que las firmas de métodos. La forma general de una firma de campo es:

    "tipo_de_campo"

La firma del campo es un símbolo codificado para el tipo del campo, encerrado entre comillas (""). Los símbolos de campos son los mismos que los símbolos de los argumentos en la firma de métodos. Esto es, un campo Integer se representa con "I", un campo float se representa con "F", un campo double "D" y un campo booleano con "Z", etc.

La firma para un objeto Java, como un String, empieza con la letra L, seguida por la clase totalmente cualificada del objeto, y terminada con un punto y coma (;). Así, se formaría la firma un campo String, como c.s en FieldAccess.java, de esta forma:

    "Ljava/lang/String;"

Los arrays se indican con un corchete abierto ([) seguido por el tipo del array. Por ejemplo, se designaría un array de Integer de esta forma:

    "[I"

Puedes referirte a la tabla de la página anterior que sumariza la codificación para las firmas Java y sus correspondientes tipos.

Se puede utilizar javap con la opción "-s" para generar firmas de campos de una clase. Por ejemplo, si se ejecuta:

    javap -s -p FieldAccess

Este da una salida que contiene las siguientes firmas de campos:

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

Ozito