skip to content

Walk through the exact order of execution when constructing an object in an inheritance hierarchy, including field initializers and chained this() calls.

level: seniorimportance: should knowfreq 52%

answer

  1. Parent first, all the way up to Object, then unwind down
  2. Per class: super() -> field inits + init blocks -> ctor body
  3. this() defers init blocks to the ctor that reaches super()
  4. Init blocks/field inits run once, not per chained ctor
  5. Overridable method in a ctor sees child fields still zero/null

basics

~20 s

First the parent is constructed top-down (via super), then each class's instance field initializers and instance blocks run, then the rest of that constructor's body. A this() call defers to the target constructor before any field initializers in that class run.

solid answer

~50 s

Object construction proceeds outermost-parent-first. For each class, the steps are: (1) the explicit or implicit super(...) call runs to fully construct the parent; (2) that class's instance field initializers and instance initializer blocks execute in source order; (3) the remaining body of the constructor runs. So for a two-level hierarchy, the order is: child constructor invoked -> super(...) -> Object initialized -> parent's field initializers and init blocks -> parent's constructor body -> child's field initializers and init blocks -> child's constructor body. A this(...) call changes this: it delegates to another constructor in the same class, and the field initializers and init blocks of that class run only as part of the constructor that does NOT delegate via this() (the one that reaches super()). This ordering is the root cause of the 'calling an overridable method from a constructor' bug: the override runs while the subclass's fields are still at their default zero values.

code

java · 11 lines
java
class Base {
    Base() { greet(); }          // calls overridable method during construction
    void greet() { System.out.println("Base.greet"); }
}
class Sub extends Base {
    String name = "set";
    @Override void greet() {
        System.out.println("Sub.greet name=" + name); // prints null!
    }
}
// new Sub() -> "Sub.greet name=null": Base() runs greet() before name="set".

go deeper

for a junior

Knows the parent is constructed before the child and that field initializers run as part of construction.

for a middle

Can order super() -> field inits/init blocks -> body for a simple hierarchy and knows static blocks are separate.

for a senior

Traces the full order including this() delegation and explains the overridable-method-in-constructor pitfall from first principles.

for a principal

Uses this ordering to reason about framework/serialization construction bugs and codifies rules (no overridable calls in ctors, final/private init helpers) across a codebase.

## The pieces involved When you write `new Child()`, several kinds of initialization code can run: - **Constructors** — `super(...)`/`this(...)` calls plus the constructor body. - **Instance field initializers** — e.g. `private int x = 5;`, the `= 5` part. - **Instance initializer blocks** — bare `{ ... }` blocks in the class body (no `static`). (Static fields and `static { }` blocks are different — they run once at *class load*, before any instance is created, and are not part of per-object construction.) ## The canonical per-object order For a single class, constructing an instance does: 1. Run the explicit `this(...)` or `super(...)` (or the implicit `super()`). 2. If step 1 was a `super(...)` (i.e. this constructor does *not* delegate to a sibling via `this(...)`), run this class's **instance field initializers and instance init blocks**, in the order they appear in source. 3. Run the rest of this constructor's body. Because `super(...)` is step 1 and it fully constructs the parent, the **parent is always completely initialized before the child's field initializers or body run**. Recursively, this means construction climbs to `java.lang.Object` first, then unwinds downward. ## Full trace for a two-level hierarchy ```java class A { int a = 1; // field init { System.out.println("A init block, a=" + a); } A() { System.out.println("A ctor body"); } } class B extends A { int b = 2; // field init { System.out.println("B init block, b=" + b); } B() { System.out.println("B ctor body"); } } ``` `new B()` prints: ``` A init block, a=1 A ctor body B init block, b=2 B ctor body ``` Expanded order: `B()` invoked -> implicit `super()` -> Object constructed -> A's field init (`a=1`) + A's init block -> A's body -> B's field init (`b=2`) + B's init block -> B's body. ## What this() changes A `this(...)` call delegates to another constructor *in the same class*. The field initializers and init blocks of that class run exactly **once**, attached to the constructor in the chain that actually calls `super(...)` (the non-delegating one). So: ```java class C { int x = 10; C() { this(99); System.out.println("no-arg, x=" + x); } // delegates C(int v) { System.out.println("int ctor, x=" + x); } // reaches super() } ``` `new C()` prints: ``` int ctor, x=10 no-arg, x=10 ``` The field initializer `x = 10` runs inside `C(int)` (the one that reaches `super()`), *before* its body; then control returns to `C()`'s body. It does **not** run twice. ## The famous pitfall: overridable method in a constructor Because the **parent constructor body runs before the child's field initializers**, calling an overridable method from a parent constructor invokes the *child's* override while the child's fields are still at their default values (0/null): ```java class Base { Base() { init(); } void init() {} } class Sub extends Base { int n = 42; @Override void init() { System.out.println(n); } // prints 0, not 42! } ``` `new Sub()` prints `0`: `Base()` calls the overridden `init()` before `n = 42` has executed. Hence the rule: **never call an overridable method from a constructor** (call only private/final/static methods, which can't be overridden). ## Why interviewers ask this It ties together overriding, dynamic dispatch, field-initializer timing, and chaining — and it explains real bugs (NPEs/zero values during construction in frameworks and serialization). Knowing the precise order lets you reason about and avoid them.

  • Why does calling an overridable method from a constructor print default field values for the subclass?
    The parent constructor body runs before the subclass's field initializers. Dynamic dispatch routes the call to the subclass override, but at that moment the subclass fields haven't been assigned, so they hold defaults (0/null/false).
  • If constructor C() calls this(99) and C(int) has a field initializer, how many times do the field initializers run?
    Once. Field initializers and init blocks run only in the constructor that reaches super() (here C(int)). The delegating C() does not re-run them; it just executes its own body afterward.
  • Do static initializers participate in this per-object order?
    No. Static fields and static blocks run once when the class is loaded/initialized, before any instance construction, and are independent of the per-object chaining order.

saying these in an interview costs you the question

  • Saying the child constructor body runs before the parent's
  • Claiming field initializers run before super() within the same class
  • Thinking init blocks run once per chained this() constructor
  • Believing dynamic dispatch is somehow disabled during construction (it is not — that is the bug)

context