Initialization order, executed
advanced14 min readLesson 121 of 180
Static vs instance init, super-first rules, and why constructors must not call overridable methods.
You already know constructors from Intermediate. Advanced Java asks a sharper question: in what exact order does anything initialize at all? The rules (JLS ยง12.2โ12.4) are mechanical, and you can observe every one of them:
- Static fields and
static {}blocks of a class run once, in source order, at class initialization (first active use). - Instance field initializers and instance initializer blocks run every time an object is created, in source order, before the constructor body.
super(...)runs before the subclass's field initializers โ so a superclass constructor that calls an overridable method sees subclass fields still null/0. This is the classic initialization trap.finalfields must be definitely assigned by the end of every constructor.
class Base {
Base() { log("Base ctor"); }
}
class Derived extends Base {
static String S = log("Derived static");
int x = log("Derived field");
Derived() { super(); log("Derived ctor"); }
}
// new Derived() prints: Derived static โ Base ctor โ Derived field โ Derived ctor
The dangerous case is virtual calls from constructors. A superclass constructor that calls an overridden method runs the override before subclass fields exist. Effective Java Item 19: constructors must not invoke overridable methods, directly or indirectly. When you need shared setup, prefer a static factory that wires fully-constructed objects.