Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Class and object initialization

Learn how to prepare classes and objects for use in an executing program

  • Print
  • Feedback

Page 3 of 9

b = true
by = 1
c = A
d = 1.2
f = 3.4
i = 2
l = 3
s = 4
st = abc


Although the output is as expected, what executes the class field initializers that explicitly initialize ClassInitializationDemo2's class fields? The answer: After the JVM zeroes the bits in all class fields, it calls a special JVM-level method to execute the byte code instructions that comprise the class's class field initializers. That method is known as <clinit>.

When you compile a class containing at least one class field initializer, the compiler generates code for <clinit>. After the JVM's class loader loads the class, after the byte code verifier verifies the class's byte codes, and after the JVM allocates memory for the class fields and zeroes all bits in those class fields, the JVM calls the class's <clinit> method (if present). The <clinit> method's byte code instructions execute all class field initializers. To see what those byte code instructions look like for the above ClassInitializationDemo2 class, check out Listing 3:

Listing 3. ClassInitializationDemo2's <clinit> method

 0   iconst_1
 1   putstatic ClassInitializationDemo2/b Z          // boolean b = true;
 4   iconst_1
 5   putstatic ClassInitializationDemo2/by B         // byte by = 1;
 8   bipush 65
10   putstatic ClassInitializationDemo2/c C          // char c = 'A';
13   ldc2_w #1.200000
16   putstatic ClassInitializationDemo2/d D          // double d = 1.2;
19   ldc #3.400000
21   putstatic ClassInitializationDemo2/f F          // float f = 3.4f; 
24   iconst_2
25   putstatic ClassInitializationDemo2/i I          // int i = 2;
28   ldc2_w #3
31   putstatic ClassInitializationDemo2/l J          // long l = 3; 
34   iconst_4
35   putstatic ClassInitializationDemo2/s S          // short s = 4;
38   ldc "abc"
40   putstatic ClassInitializationDemo2/st Ljava/lang/String;  // String st = "abc";
43   return


Listing 3 presents some insight into how ClassInitializationDemo2's <clinit> method works. Each line presents a number and a byte code instruction. The number represents the instruction's zero-based address and is not important to this discussion. The first instruction, iconst_1, pushes integer constant 1 onto a stack, and the second instruction, putstatic ClassInitializationDemo2/b Z, pops that constant from the stack and assigns it to boolean class field b. (At the JVM level, at least with Sun's JVM, the Boolean true value is represented as integer constant 1.) The Z appearing to the right of the putstatic instruction identifies the type of b as Boolean. Similarly, B identifies the byte type, C identifies the character type, D identifies the double-precision floating-point type, F identifies the floating-point type, J identifies the long integer type, and S identifies the short integer type. The bipush, ldc2_w, ldc, and other iconst instructions push other constants onto the stack, and their respective putstatic instructions pop those values from the stack before assigning them to various class fields. The final return instruction causes execution to leave the <clinit> method. At that point, the main() method starts to execute.

  • Print
  • Feedback

Resources