Accessing Java Object Fields in JBI

Accessing instance fields through JBI is possible, but much less efficient than passing values via function arguments. For this reason, you are encouraged to use this feature only if no alternative is available or performance is of secondary importance.

To access a field, the field descriptor must first be obtained from the class that defines the field. This class can be obtained from an instance of this class through the macro JAMAICA_GET_CLASS_OF_OBJECT(ct,obj). The arguments of this macro are the current thread and a jamaica_ref reference to the object; the result is a referenc to the class of type jamaica_ref. The field can then be found using the macro JAMAICA_FIND_FIELD(ct,clazz,name,type). This macro also requires access to the current thread ct and the class reference obtained from JAMAICA_GET_CLASS_OF_OBJECT. The field itself is identified by its name and type. These two values are C strings (of type char *) that use the same UTF8 encoding that is used with Java class files. As long as only 7 bit ASCII values are used, the UTF8 encoding is the same as a plain ASCII string.

Once the field structure has ben obtained, the field can be read using the apropriate macro:

Corresponding macros exist for writing fields:

The following example illustrates accessing of fields. A native method is used to determine whether the float value in field a is a not-a-number (nan) value. The result of this native method is stored in field is_nan. The Java declaration of this routine and the fields looks as follows.

	  
  public float   a; 
  public boolean is_nan; 
  public native void is_a_nan();
	  
	

The C code is:

	  
void Jam_Test_is_1a_1nan(
    jamaica_thread *ct, 
    jamaica_ref thiz) {

  jamaica_ref clazz, field_a, field_is_nan;
  jamaica_int32 is_nan; 
  jamaica_float a; 

  /* protect array from being GC'ed */
  Jamaica_SaveLocal(ct,thiz);
  {  
    /* permit thread switch */
    JAMAICA_SYNCHRONIZATION_POINT(ct); 

    clazz = JAMAICA_GET_CLASS_OF_OBJECT(ct,thiz); 
    field_a      = JAMAICA_FIND_FIELD(ct,
                                      clazz,
                                      "a",
                                      "F");
    field_is_nan = JAMAICA_FIND_FIELD(ct,
                                      clazz,
                                      "is_nan",
                                      "Z");
    if ((field_a      != JAMAICA_NULL) &&
        (field_is_nan != JAMAICA_NULL)    ) {
      JAMAICA_GET_FLOAT_FIELD(ct,thiz, field_a,a); 
      is_nan = isnan(a) ? JAMAICA_TRUE : JAMAICA_FALSE; 
      JAMAICA_SET_BOOLEAN_FIELD(ct,
                                thiz,
                                field_is_nan,
                                is_nan);
    }
  }
  Jamaica_ReleaseLocal(ct);  /* thiz */
}
	  
	

Note that the reference values for clazz, field_a and field_is_nan usually need to be protected using Jamaica_SaveLocal(ct,thiz). In this example, however, clazz remains reachable since thiz is saved. The same holds for field_a and field_is_nan: Since the class that contains these fields is reachable from thiz, the fields do not need to be saved either.