Walk through the exact order of operations when you call new on a subclass: default values, super constructor, instance initializers, field initializers, and the constructor body. Why is this order important?
answer
- defaults → super → my initializers/blocks → my body
- parent fully built before child
- field initializers run after super, before body
- virtual call in ctor sees default child fields
- textual order within a class
basics
~20 sOn new: fields first get default values (0/null/false), then the parent constructor runs fully, then this class's instance field initializers and instance blocks run top-to-bottom, and finally the constructor body runs. Parent is always fully built before the child.
solid answer
~50 sWhen you call new on a subclass, the JVM first allocates the object and zeroes all instance fields to defaults (0, false, null). Then the chosen constructor runs: its first action is to call super(...) (implicit if you didn't write it), so the entire parent chain is constructed top-down before the child does anything. After super returns, this class's instance field initializers and instance initializer blocks run in textual order, interleaved as written. Only then does the rest of the constructor body execute. This order guarantees the parent is fully initialized before the child's logic runs and before the child's own fields are set. The classic gotcha: if a parent constructor calls an overridden method, it runs the child's override while the child's fields are still at their default values, because child field initializers haven't run yet.
go deeper
Knows the parent constructor runs before the child constructor body.
Can recite defaults → super → field initializers/blocks → body and explain the virtual-call trap.
Reasons about this(...) chaining, why initializers run once, and safe-construction patterns (avoid overridable calls in ctors).
Frames it as an invariant for safe object construction and immutability/final-field publication guarantees across the hierarchy.
## Setup *Initialization order* is the precise sequence of steps the JVM takes between `new Child()` and you getting back a usable object. "Default values" means the zero value Java assigns to every field before your code touches it: `0` for numbers, `false` for boolean, `null` for references. A *constructor* is the special method invoked by `new`. *Instance field initializers* are the `= value` parts of field declarations; *instance initializer blocks* are bare `{ ... }` blocks in the class body. *super(...)* calls the parent constructor. ## The full per-object sequence (for `new Child()`) 1. **Allocate + default-zero all fields** of the whole object (parent and child fields) to 0/false/null. 2. **Invoke the Child constructor.** Its very first statement is `super(...)` — explicit, or an implicit no-arg `super()` the compiler inserts. (You may instead chain to another constructor with `this(...)`, which eventually reaches a `super(...)`.) 3. **Construct the parent fully first.** Recursively, the parent's `super(...)` runs, up to `Object`. Then for each class going *down* the chain: a. that class's **instance field initializers and instance blocks** run in **textual (top-to-bottom) order**, then b. that class's **constructor body** runs. 4. Control returns to `Child`: **Child's instance field initializers and instance blocks** run in textual order. 5. **Child's constructor body** runs. 6. `new` returns the reference. So the rule per class is: **super first → my field initializers/blocks (in order) → my constructor body.** ## Example ```java class Parent { Parent() { System.out.println("Parent ctor; show()="); show(); } void show() { System.out.println("Parent.show"); } } class Child extends Parent { int value = 42; // field initializer { System.out.println("Child instance block"); } Child() { System.out.println("Child ctor, value=" + value); } @Override void show() { System.out.println("Child.show, value=" + value); } } ``` Running `new Child()` prints: ``` Parent ctor; show()= Child.show, value=0 <-- !! override called, value still default 0 Child instance block Child ctor, value=42 ``` ## Why the order matters - It guarantees the **parent is fully built before the child** uses inherited state — your child constructor can safely rely on parent fields. - It explains the **virtual-call-in-constructor trap** (line 2 above): the parent constructor calls `show()`, which dynamically dispatches to `Child.show`, but `Child`'s field initializer (`value = 42`) hasn't run yet, so `value` is still `0`. This is why calling overridable methods from a constructor is dangerous. - It explains why a field set in a declaration initializer can be **overwritten** by the constructor body (the body runs last). ## Mental model Think of it as building a house: lay the foundation (parent) completely, then build each floor (each subclass) by first stocking its rooms (field initializers/blocks) and then doing finishing work (constructor body).
- Why does calling an overridable method from a constructor print a default field value?Dynamic dispatch picks the subclass override, but it runs during the parent constructor — before the subclass field initializers run — so the field is still at its default (0/null/false).
- What happens if you use this(...) instead of super(...) in a constructor?It delegates to another constructor of the same class; field initializers run only once, after the delegated chain finally reaches a super(...), so duplicate initialization is avoided.
saying these in an interview costs you the question
- Thinking child field initializers run before the super constructor
- Assuming a method called from the parent constructor sees initialized child fields
- Believing the constructor body runs before field initializers
- Forgetting the implicit super() the compiler inserts