When you call new on a class with a parameterized constructor, what runs and in what order (including super, field initializers, and the constructor body)?
answer
- super() first → parent fully built first
- then field initializers + instance blocks, in source order
- constructor body last
- enters bottom-up, completes top-down
- never call overridable methods from a constructor
- static initializers run once at class load, separately
basics
~20 sFirst the parent class is built (super runs), then this class's field initializers and instance initializer blocks run top to bottom, and finally the rest of your constructor body runs. So the parent is always fully set up before your constructor code executes.
solid answer
~40 sFor each class level, `new` triggers a fixed sequence. The constructor's first action is the `super(...)` call (explicit, or an implicit `super()`), which fully constructs the superclass first — recursing up to `Object`. Then, back in this class, the **instance field initializers and instance initializer blocks run in source order**, before the rest of the constructor body. Finally the remaining statements of the constructor body execute. So bottom-up the call enters, but top-down (parent-first) the work completes. A subtle consequence: if a superclass constructor calls an overridden method, it runs the subclass override while the subclass's own fields are still at their default values (not yet initialized) — a well-known pitfall. Static initializers are separate: they run once at class loading, before any instance is created.
code
java · 18 linesclass Base {
Base() { System.out.println("1: Base ctor"); init(); }
void init() { System.out.println("Base.init"); }
}
class Sub extends Base {
int v = setV(); // field initializer (step 3)
{ System.out.println("3: Sub instance block, v=" + v); }
int setV() { System.out.println("2-or-3: setV"); return 7; }
@Override void init() { System.out.println("2: Sub.init, v=" + v); } // v still 0 here!
Sub() { System.out.println("4: Sub ctor, v=" + v); }
}
// new Sub():
// 1: Base ctor
// 2: Sub.init, v=0 (override called from Base ctor, before Sub fields set)
// 2-or-3: setV
// 3: Sub instance block, v=7
// 4: Sub ctor, v=7go deeper
Knows the parent is constructed before the child and the constructor body runs after fields get values.
Can order super → field initializers/instance blocks → constructor body, and knows static init is separate.
Explains the bottom-up-enter/top-down-complete model and the overridable-method-in-constructor pitfall with the default-value consequence.
Reasons about safe construction at scale: leaking-this, partially constructed objects across threads/visibility, and design rules (final, factories) that prevent these hazards.
## The question being answered When you write `new Sub(args)` and `Sub extends Base extends Object`, several pieces of code can run: superclass constructors, **field initializers** (`int x = 5;`), **instance initializer blocks** (`{ ... }`), and the constructor body. Knowing the exact order explains a class of real bugs. ## Terms - **Field initializer**: the `= value` part of an instance field declaration, e.g. `private int x = compute();`. - **Instance initializer block**: a bare `{ ... }` block (no `static`) inside the class body; its code is copied into every constructor. - **Static initializer**: `static { ... }` block and static field initializers — run **once when the class is loaded**, before any instance exists. (Separate from instance construction.) - **super(...)**: the call to a superclass constructor; **first statement** of any constructor (implicit `super()` if you omit it). ## The precise order for one `new` 1. **Memory is allocated** for the object; all instance fields are set to their **default values** (0, false, null). 2. The chosen constructor runs. Its **first action is `super(...)`** — so the **superclass is fully constructed first**, applying steps 1–4 recursively up to `Object`. 3. After `super(...)` returns, **this class's instance field initializers and instance initializer blocks execute in the order they appear in the source**. 4. The **rest of the constructor body** runs. So construction *enters* bottom-up (Sub's constructor is called first) but *completes* top-down (Object first, then Base, then Sub). By the time your subclass constructor body runs, every ancestor is fully built. ```java class Base { Base() { System.out.println("Base ctor"); show(); } void show() { System.out.println("Base.show"); } } class Sub extends Base { int value = 42; { System.out.println("Sub init block"); } Sub() { System.out.println("Sub ctor, value=" + value); } @Override void show() { System.out.println("Sub.show, value=" + value); } } // new Sub() prints: // Base ctor // Sub.show, value=0 <-- override called from Base ctor, value NOT yet set! // Sub init block // Sub ctor, value=42 ``` ## The classic pitfall In step 2, the **superclass constructor runs before** the subclass's field initializers (step 3). If the superclass constructor calls a method that the subclass **overrides**, the override executes while the subclass's fields are still at defaults — above, `value` is `0`, not `42`. Hence the rule: **don't call overridable (non-final, non-private) methods from a constructor.** ## Static vs instance Static initializers run **once, at class load time**, strictly before the first instance is created or the first static member is used — they are not part of per-`new` instance construction at all. ## Why it matters This ordering underlies safe initialization, the 'leaking this' problem, why `final` fields can rely on construction completing, and subtle framework bugs where a base class touches not-yet-initialized subclass state.
- Why shouldn't a constructor call an overridable method?Because a subclass override may run before the subclass's own fields are initialized, seeing them at default values. The method observes a half-built object. Use private or final methods, or factory methods, instead.
- Where do static initializers fit in this order?They don't — they run once when the class is loaded, before any instance is constructed. Instance construction (super/field/block/body) happens per new, after the class is already loaded.
saying these in an interview costs you the question
- Saying the subclass constructor body runs before super() (it can't; super is first)
- Claiming field initializers run before super() returns
- Conflating static initializers (once, at load) with instance construction (per new)
- Assuming an overridden method called from a super-constructor sees initialized subclass fields