All topics
library
intermediate

Initialization Blocks: Static & Instance

Understand the order of execution of static blocks, instance blocks, constructors, and field initializers.

An initialization block is code in braces that runs automatically — not inside any method.

Static block = setting up the factory before any product is made (happens once). Instance block = quality check on the assembly line (happens for every product before it ships).

Key Concepts

1
    class Example {
        static { System.out.println("static block"); }   // once, ever
        { System.out.println("instance block"); }        // every new object
        Example() { System.out.println("constructor"); }
    }
2
A static block runs once, the first time the class is used. An instance block runs every time you create an object, just before the constructor body.
static
3
The order, for new Child() where Child extends Parent.
  1. Parent's static fields and static blocks     once, ever
  2. Child's static fields and static blocks      once, ever
  3. Parent's instance fields and blocks          every object
  4. Parent's constructor body
  5. Child's instance fields and blocks
  6. Child's constructor body
new Child()
4
Static before instance. Parent before child. That is the whole rule.
5
"The first time the class is used" is more precise than it sounds. Creating an object counts. Calling a static method counts. Reading a normal static field counts.
6
Reading a static final constant does not, because the compiler copies the value into your code and the class is never touched.
static final
7
The bug this causes. Step 4 runs before step 5. So if a parent constructor calls a method the child has overridden, the child's version runs before the child's fields exist:
8
    class Parent {
        Parent() { init(); }             // calls the child's version
        void init() { }
    }
    class Child extends Parent {
        private String name = "set";     // assigned at step 5
        @Override void init() {
            System.out.println(name);    // prints null
        }
    }
9
The object is real enough to call methods and not yet real enough to answer them. This is why you never call an overridable method from a constructor.
10
A failing static block poisons the class permanently. If a static block throws, you get ExceptionInInitializerError once. Every later attempt to use that class throws NoClassDefFoundError with no explanation of the original cause.
ExceptionInInitializerErrorNoClassDefFoundError
11
In a long-running service, only the first failure in the log is useful and everything after it is misleading. Keep static blocks trivial, and put anything that can fail behind an initialisation method you call deliberately.
12
What the interviewer is probing.1. "What order do these run in?" Probing: precision. Stalls: "Constructor first." Moves up: the six steps, static before instance, parent before child.
13
2. "When does a static block run?" Probing: what triggers it. Stalls: "When the class loads." Moves up: loading and initialising are different; it runs on first real use, and a compile-time constant does not count.
14
3. "Why not call an overridable method from a constructor?" Probing: the real bug. Stalls: "Bad practice." Moves up: the override runs before the subclass fields are assigned, so it sees nulls.
15
4. "A static block throws. What happens?" Probing: failure behaviour. Stalls: "An exception." Moves up: one ExceptionInInitializerError, then NoClassDefFoundError forever.
ExceptionInInitializerErrorNoClassDefFoundError
16
5. "Instance block or constructor?" Probing: judgement. Stalls: "They are the same." Moves up: blocks share setup between several constructors, but a private method is usually clearer.
17
  Order for `new Child()` where Child extends Parent
new Child()
18
  1   Parent static fields + static blocks      once, in source order
  2   Child  static fields + static blocks      once, in source order
  3   Parent instance fields + instance blocks  every construction
  4   Parent constructor body
  5   Child  instance fields + instance blocks
  6   Child  constructor body
19
  What triggers step 1/2 (class initialisation)
    new Child()                                    yes
    Child.staticMethod()                           yes
    Child.NON_CONSTANT_FIELD                       yes
    Child.COMPILE_TIME_CONSTANT  (static final
      int = 42)                                    NO - inlined
    Class.forName("Child")                         yes
    Child.class literal                            no
20
  The constructor trap
21
    class Parent {
        Parent() { init(); }            // calls the override
        void init() { }
    }
    class Child extends Parent {
        private String name = "set";    // runs AFTER Parent()
        @Override void init() {
            System.out.println(name);   // prints null
        }
    }