What is the difference between static and instance initializer blocks, and what order do they run in?
Quick Answer
A static block runs once when the class is first loaded, before any instance exists. An instance initializer block runs every time a new object is constructed, right before the constructor body, after the superclass constructor has run. Order overall: static blocks/fields (in source order, once) -> instance blocks/fields -> constructor body, each time an object is created.
Detailed Answer
Java has two kinds of initializer blocks, run at different times:
- Static initializer block (
static { ... }): runs exactly once, when the class is first loaded/initialized by the JVM — before any instance is created and beforemain()even, if that class contains it. - Instance initializer block (
{ ... }, nostatic): runs every time a new instance is constructed, right after the superclass constructor completes and before the current class's constructor body executes.
Full order when creating an object of a subclass for the first time:
- Superclass static blocks/fields (in source order) — once, on first load.
- Subclass static blocks/fields (in source order) — once, on first load.
- For each
newcall: superclass constructor runs (which itself runs superclass instance blocks, then its constructor body) → subclass instance blocks/field initializers (in source order) → subclass constructor body.
class Base {
static { System.out.println("Base static"); }
{ System.out.println("Base instance"); }
Base() { System.out.println("Base ctor"); }
}
class Derived extends Base {
static { System.out.println("Derived static"); }
{ System.out.println("Derived instance"); }
Derived() { System.out.println("Derived ctor"); }
}
new Derived();
// Base static, Derived static, Base instance, Base ctor, Derived instance, Derived ctor
Static blocks are useful for one-time setup (loading config, registering drivers); instance blocks are less common than field initializers but useful for logic that field initializers can't express (e.g., a switch during setup) shared by every constructor.