skip to content

How does constructor chaining with this(...) interact with instance field initializers and instance blocks, and how many times do those initializers run?

level: middleimportance: nice to knowfreq 28%

answer

  1. this(...) delegates within the class
  2. field initializers run once, after super returns
  3. only the super-calling ctor runs initializers
  4. delegating ctor skips re-init
  5. put shared setup where super is called

basics

~20 s

When a constructor calls this(...) to delegate to another constructor of the same class, the instance field initializers and instance blocks run only once, in the constructor that actually calls super(...). Delegating constructors do not re-run them.

solid answer

~50 s

A constructor's first statement is either super(...) or this(...). With this(...), the constructor delegates to another constructor of the same class instead of calling super directly. The instance field initializers and instance initializer blocks run exactly once per object, immediately after the super(...) call returns — which happens only in the constructor at the end of the delegation chain that actually invokes super. Constructors that begin with this(...) skip running the field initializers themselves; they rely on the delegated-to constructor to have already run them. So if constructor A does this(), and the no-arg constructor calls super() then sets fields, the field initializers run once (when super returns in the no-arg constructor), then the no-arg body runs, then control returns to A and A's body runs. This prevents fields from being initialized twice and is why you put common setup in the constructor that calls super.

go deeper

for a junior

Knows this(...) calls another constructor in the same class.

for a middle

Knows field initializers run once, after super returns, only in the super-calling constructor.

for a senior

Designs constructor chains so shared setup runs once and avoids duplicate initialization.

for a principal

Reasons about constructor design for immutability/final fields and telescoping-constructor or builder alternatives.

## Terms *Constructor chaining* is when one constructor calls another. Two forms: - `super(...)` — calls a **superclass** constructor. - `this(...)` — calls **another constructor of the same class**. Every constructor's first statement is one of these (the compiler inserts an implicit `super()` if you write neither). *Instance field initializers* are the `= value` parts of field declarations; *instance initializer blocks* are bare `{ ... }` blocks. ## The key rule Instance field initializers and instance blocks run **exactly once per object**, **immediately after `super(...)` returns**. They are effectively spliced in right after the super call — but **only in the constructor that actually calls `super(...)`**. A constructor that starts with `this(...)` does **not** run them again; it depends on the delegated constructor having run them. ## Walkthrough ```java class Widget { int size = 10; // field initializer { System.out.println("block, size=" + size); } // instance block Widget() { // calls super() implicitly System.out.println("no-arg body"); } Widget(String label) { this(); // delegate to no-arg System.out.println("label body"); } } ``` `new Widget("x")` runs: 1. `Widget(String)` starts with `this()` → jump to `Widget()`. 2. `Widget()` starts with implicit `super()` → `Object()` runs. 3. **Now** the field initializer `size = 10` and the instance block run (once), printing `block, size=10`. 4. `Widget()` body runs → prints `no-arg body`. 5. Control returns to `Widget(String)` body → prints `label body`. Output: ``` block, size=10 no-arg body label body ``` Note the field/block initialization happened **once**, in the no-arg constructor (the one calling super), not in the `Widget(String)` that started the chain. ## Why it works this way If field initializers ran in every constructor, delegating constructors would re-initialize fields and clobber work done by the delegated-to constructor. Running them once, right after the single `super` call in the chain, keeps each field set exactly once before any constructor body logic. ## Practical guidance - Put **shared field setup** in the constructor that calls `super(...)`; have other constructors delegate via `this(...)`. - Don't expect field initializers to re-run in a delegating constructor. - Field initializers always run before **any** constructor body in the chain, so all bodies can rely on them.

  • Can a constructor call both this(...) and super(...)?
    No. A constructor's first statement is exactly one of them; calling this(...) eventually leads to a constructor that calls super(...).
  • Where should you put initialization shared by several constructors?
    In the constructor that ultimately calls super(...), and have the others delegate to it via this(...), so the shared setup runs once.

saying these in an interview costs you the question

  • Thinking field initializers run once per constructor invoked in the chain
  • Believing this(...) and super(...) can both be called in one constructor
  • Assuming a delegating constructor re-runs instance blocks

context