Initializer blocks & init order in Java
Static blocks once at class init; instance blocks before the constructor body.
static { } block and a plain { } block, then create two objects. Most people guess the order wrong the first time. Will you?Two kinds of setup
Class setup happens once; object setup happens on every new. A static { } block is class setup: it runs once, when the class is first initialized.
class Demo {
static { System.out.print("S"); }
}Instance blocks
A plain { } block in a class body is an instance initializer. It runs on **every new, together with field initializers in source order, and all of them run before the constructor body**.
class Demo {
{ System.out.print("I"); }
Demo() { System.out.print("C"); }
}
// new Demo() prints ICOpen the gate twice
What does this print?
class Gate {
static { System.out.print("1"); }
{ System.out.print("2"); }
Gate() { System.out.print("3"); }
}
void main() {
new Gate();
new Gate();
}12312312323231231323
Show the answer
12323. The static block prints 1 once, when Gate is initialized. Each new then runs the instance block (2) before the constructor body (3).
Source order wins
Field initializers and instance blocks are merged top to bottom, then the constructor body runs last. Here the order is a, block, b, ctor.
class Order {
int a = log("a");
{ log("block"); }
int b = log("b");
Order() { log("ctor"); }
}When does the class wake up?
Classes are initialized lazily, on first active use. What prints?
class Cfg {
static { System.out.print("load "); }
static int port = 80;
}
void main() {
System.out.print("go ");
System.out.print(Cfg.port);
}load go 80go load 80go 80
Show the answer
go load 80. Cfg isn't touched until Cfg.port is read — a non-constant static field — which triggers its static block right then.
Constants don't wake the class
A static final field with a compile-time constant value is copied into the caller by the compiler. Reading it does not initialize the class — so the static block below never runs: this prints just 7.
class K {
static { System.out.print("init "); }
static final int X = 7; // constant
}
// System.out.print(K.X); -> 7In real projects
Static blocks load configuration, build lookup tables and load native libraries (static { System.loadLibrary("x"); } is a common JNI pattern). Old JDBC drivers registered themselves in a static block — that's why code used to call Class.forName("...Driver").
Key takeaways
- static { } runs once per class, at first active use
- Instance initializers and { } blocks run in source order
- They run before the constructor body, on every new
- Reading a non-constant static field triggers class init
If a static initializer throws, the class becomes unusable: the first use fails with ExceptionInInitializerError, and every later use with NoClassDefFoundError.
Practice questions
What does this print?
class Demo {
static { System.out.print("S"); }
{ System.out.print("I"); }
Demo() { System.out.print("C"); }
}
void main() {
new Demo();
new Demo();
}- SICSIC
- SICIC
- ICSIC
- SCICI
Check your answer
SICIC. S prints once when Demo is initialized. Each new then runs the instance block (I) before the constructor body (C).
What does this print?
class Order {
int a = log("a");
{ log("block"); }
int b = log("b");
Order() { log("ctor"); }
static int log(String s) {
System.out.print(s + " "); return 0;
}
}
void main() { new Order(); }- a b block ctor
- a block b ctor
- block a b ctor
- ctor a block b
Check your answer
a block b ctor. Field initializers and instance blocks are merged in source order (a, block, b) and run before the constructor body.