skip to content

Within a single class, when do instance field initializers and instance initializer blocks run relative to super(...) and the rest of the constructor body?

level: middleimportance: should knowfreq 40%

answer

  1. Order: super() → field inits + init blocks (source order) → constructor body
  2. Field initializers and init blocks interleave by textual position
  3. this(...) means inits run once, in the constructor that calls super()
  4. Static initializers run at class load, not per object
  5. Body runs last, so it can rely on initialized fields

basics

~20 s

First the superclass is constructed via super(...). Then, in source order, the class's field initializers and instance-initializer blocks run. Then the rest of the constructor body runs. So initializers come after super() but before your constructor code.

solid answer

~50 s

For one class, object initialization proceeds in a fixed order: (1) the implicit or explicit `super(...)` call constructs the superclass; (2) the class's *instance field initializers* (like `int x = 5;`) and *instance initializer blocks* (`{ ... }`) run together, interleaved in the exact source order they appear; (3) the remaining statements of the constructor body run. If the constructor instead starts with `this(...)`, steps 2 and 3 are skipped for *this* constructor and happen only once, in the constructor that the chain ultimately reaches before its body. This is why a constructor can rely on field initializers having already run by the time its body executes, and why initializer blocks are a place to put setup shared by multiple constructors. It also explains the half-built-object hazard: during the superclass's construction (step 1), none of these subclass initializers have run yet.

go deeper

for a junior

Knows the constructor body runs and fields get their declared values; may not order initializers vs super precisely.

for a middle

States the full per-class order (super → initializers/blocks in source order → body) and that init blocks run for every non-delegating constructor.

for a senior

Handles the this(...) delegation exception (inits run once), interleaving by source order, and connects it to the parent-first/half-built hazard.

for a principal

Reasons about using initializer blocks vs constructors for shared setup and immutability, and distinguishes instance vs static initialization phases cleanly across a hierarchy.

**Terms.** An *instance field initializer* is the `= value` part of a field declaration, e.g. `private int count = 10;` — it runs per object. An *instance initializer block* is a bare `{ ... }` block at class level (no `static`, no method name); its code also runs per object. A *constructor body* is the code inside `ClassName(...) { ... }` after any leading `this(...)`/`super(...)` call. **The per-class sequence.** When an object of class `C` is being constructed, for the level of `C` itself the order is strictly: 1. **`super(...)`** — explicit, or the compiler-inserted no-arg `super()`. This fully constructs the superclass portion first. 2. **Field initializers + instance initializer blocks, in source order.** They are *not* grouped by kind — a field initializer on line 3 runs before an init block on line 5 which runs before a field initializer on line 7. They execute as one merged sequence following textual order. 3. **The rest of the constructor body** — every statement after the leading `super(...)`/`this(...)`. **The `this(...)` exception.** If a constructor's first statement is `this(...)` (delegating to another constructor of the same class), then for *that* constructor, steps 2 is **not** repeated — field initializers and init blocks run exactly once, in whichever constructor in the chain actually invokes `super(...)`. This prevents fields from being initialized twice when constructors delegate to each other. **Across a hierarchy.** Combine this with parent-first construction: for `Derived extends Base`, `new Derived()` runs — Base's `super()`(→Object) → Base's field initializers/blocks → Base's constructor body → (back in Derived) Derived's field initializers/blocks → Derived's constructor body. So every class's initializers run sandwiched between its `super(...)` and its own constructor-body statements. **Why it matters.** - **Shared setup:** an instance initializer block runs for *every* constructor (that doesn't delegate via `this(...)`), so it's a place to centralize common initialization without duplicating it in each constructor. - **Field readiness:** because initializers run before the constructor body, the body can safely use the initialized fields. - **The half-built hazard (cross-reference):** because subclass initializers are step 2 *after* the superclass's step 1 completes, they have **not** run while the superclass constructor executes — the root cause of the 'overridable method in constructor' bug. **Static vs instance.** *Static* field initializers and *static* initializer blocks (`static { ... }`) are different: they run once, in source order, when the class is first initialized (loaded), before any instance exists — not part of per-object construction. **Worked example.** Given a class with `int a = 1;`, then `{ a = 2; }`, then a constructor body `a = 3;`, after construction `a == 3`: the initializer sets 1, the block sets 2 (source order), the body sets 3 last.

  • If a constructor delegates with this(...), do field initializers run twice?
    No. Field initializers and instance blocks run exactly once, in whichever constructor in the chain ultimately calls super(...). The this(...)-delegating constructor only runs its own body afterward.
  • Given `int x = 1;` then a block `{ x = 2; }` then constructor body `x = 3;`, what is x?
    3. The initializer (1) and block (2) run in source order after super(), then the body runs last and sets 3.

saying these in an interview costs you the question

  • Thinking field initializers run before super() — they run after it returns
  • Assuming all field initializers run, then all init blocks — they interleave in source order
  • Confusing static init blocks (once, at class load) with instance init blocks (per object)
  • Believing this(...) re-runs the field initializers in each delegating constructor

context