As it turns out the compiler generates a second static constructor besides the default constructor. Look at the class and corresponding bytecode below:
/** * */ public class ClassWithStaticBlock { static int i; static { i = 2; } }
You can lookup the bytecode mnemonics here.
// class version 49.0 (49) // access flags 0x21 public class ClassWithStaticBlock { // compiled from: ClassWithStaticBlock.java // access flags 0x8 static I i // access flags 0x1 // generated default constructor public ()V L0 LINENUMBER 4 L0 ALOAD 0 INVOKESPECIAL java/lang/Object. ()V RETURN L1 LOCALVARIABLE this LClassWithStaticBlock; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x8 // static constuctor static ()V L0 LINENUMBER 8 L0 ICONST_2 // push int value 2 on the operand stack PUTSTATIC ClassWithStaticBlock.i : I // pop value off the stack and assign it to the static field L1 LINENUMBER 9 L1 RETURN MAXSTACK = 1 MAXLOCALS = 0 }