Next: , Previous: Objects and Classes, Up: About CNI


11.7 Class Initialization

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 JvInitClass 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++.