Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
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
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.