Soumya Das Soumya Das - 2 months ago 12
Java Question

Clarification about GetFieldID

I was trying to build a native method and although it seems to run fine, but I am struggling to understand a field [*sig] in a function -

jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);


https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

For example I have a small Java code, which uses an instance variable called "i" and all this native method(named test) does is multiply this by 2.

Now I am referring to Java Complete Reference book - here the code goes like -

My question is - what is "I" in this -
fid = (*env)->GetFieldId(env,cls,"i", "I");

When I read Oracle documenttion it says -
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html


Accessing Fields of Objects

GetFieldID


jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);



Returns the field ID for an instance (nonstatic) field of a class. The field is specified by its name and signature. The GetField and SetField families of accessor functions use field IDs to retrieve object fields.

GetFieldID() causes an uninitialized class to be initialized.

GetFieldID() cannot be used to obtain the length field of an array. Use GetArrayLength() instead.

LINKAGE:

Index 94 in the JNIEnv interface function table.

PARAMETERS:

env: the JNI interface pointer.

clazz: a Java class object.

name: the field name in a 0-terminated modified UTF-8 string.

sig: the field signature in a 0-terminated modified UTF-8 string.


Could you please may be elaborate what is this field "sig"? I couldn't relate "I" with anything.

#include <jni.h>
#include "NativeDemo.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env , jobject obj)
{
jclass cls;
jfieldID fid;
jint i;

printf("Starting the native method\n");

cls = (*env)->GetObjectClass(env,obj);
fid = (*env)->GetFieldId(env,cls,"i", "I");

Answer

please see the "employee" example below in Core Java, v. 2 ch. 12, by Horstmann and Cornell at http://www.horstmann.com/corejava.html the "id" is the name of the field, here private double salary; inside the Employee class; its signature ("sig"), or type, "D" (double) also must be specified. in your code, "I" is integer. see the "Type Fields" at http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html once the jFieldId is obtained, it can be used to modify the value of the field.

/**
  @version 1.10 1999-11-13
  @author Cay Horstmann
*/

#include "Employee.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_Employee_raiseSalary(JNIEnv* env, jobject     this_obj, jdouble byPercent)
{  
   /* get the class */
   jclass class_Employee = (*env)->GetObjectClass(env, this_obj);

   /* get the field ID */
   jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D");

   /* get the field value */
   jdouble salary = (*env)->GetDoubleField(env, this_obj, id_salary);

   salary *= 1 + byPercent / 100;

   /* set the field value */
   (*env)->SetDoubleField(env, this_obj, id_salary, salary);
}