Next: Object allocation, Previous: Objects and Classes, Up: About CNI
Java requires that each class be automatically initialized at the time
of the first active use. Initializing a class involves
initializing the static fields, running code in class initializer
methods, and initializing base classes. There may also be
some implementation specific actions, such as allocating
String
objects corresponding to string literals in
the code.
The GCJ compiler inserts calls to JvInitClass
at appropriate
places to ensure that a class is initialized when required. The C++
compiler does not insert these calls automatically—it is the
programmer's responsibility to make sure classes are initialized.
However, this is fairly painless because of the conventions assumed by
the Java system.
First, libgcj
will make sure a class is initialized before an
instance of that object is created. This is one of the
responsibilities of the new
operation. This is taken care of
both in Java code, and in C++ code. When G++ sees a new
of a
Java class, it will call a routine in libgcj
to allocate the
object, and that routine will take care of initializing the class.
Note however that this does not happen for Java arrays; you must
allocate those using the appropriate CNI function. It follows that
you can access an instance field, or call an instance (non-static)
method and be safe in the knowledge that the class and all of its base
classes have been initialized.
Invoking a static method is also safe. This is because the
Java compiler adds code to the start of a static method to make sure
the class is initialized. However, the C++ compiler does not
add this extra code. Hence, if you write a native static method
using CNI, you are responsible for calling JvInitClass
before doing anything else in the method (unless you are sure
it is safe to leave it out).
Accessing a static field also requires the class of the
field to be initialized. The Java compiler will generate code
to call Jv_InitClass
before getting or setting the field.
However, the C++ compiler will not generate this extra code,
so it is your responsibility to make sure the class is
initialized before you access a static field from C++.