: code tutorial (v3)

Lesson 6: Accessing Fields

Introduction

Accessing the field members of Java objects via proxy types is as easy as it is in pure Java. The only thing to remember is that C++ uses a double colon instead of a period to reference a static type member.

Given a Java type like

public class DataType {
    public final static String   STATIC_DATA = "test";
    public int                   i;
    public Object                obj;
}

we can write the following C++ code:

DataType  dt( _use_java_ctor );

dt.i = 4;
dt.i += 7;
dt.obj = "string value";

assert( dt.i == 11 );
assert( DataType::STATIC_DATA.equals( "test" ) );

There is of course a lot of heavy-lifting going on behind the scenes to make this happen and that is particularly true for fields of primitive type. As you can imagine, the type of field i in C++ is not really int. If it were a primitive type, how could we get and set a value on the Java side when we use it? Instead, every primitive Java field is translated to a corresponding field type that supports all operators you would expect, including of course the conversions to and from its primitive type. That type has all the smarts to translate the operations you perform on it in C++ to get or set operations on the Java side. You never use these field types explicitly. The only place where they are used is inside generated proxy types.

Patterns to Avoid

As you can see from the snippet above, this works remarkably well and is almost completely transparent to the developer. But nothing this complex can ever be perfect. There is one particular area where you can run into trouble. If you read the lesson on strings you have already encountered it: it is the printf() family of functions. Let's take a look at what you might want to write:

DataType dt( _use_java_ctor );

dt.i = 4;

printf( "dt.i = %d\n", dt.i );

The above snippet has a format argument that states that it expects to be invoked with one additinal integer argument. But dt.i is not an integer, it's one of our smart fields.

This is fixed easily enough by simply casting the field explicitly, as in:

DataType dt( _use_java_ctor );

dt.i = 4;

printf( "dt.i = %d\n", (int)dt.i );