How does super() work in constructors, and what are the rules for constructor chaining in an inheritance hierarchy?
answer
- super()/this() must be the first statement
- no explicit call → implicit no-arg super()
- parent needs an accessible no-arg ctor or you must call super(args)
- bodies run top-down (Object first)
- this() and super() are mutually exclusive
basics
~10 ssuper(...) calls a parent constructor and must be the first statement in a subclass constructor. If you don't write it, Java inserts a no-arg super() automatically so the parent is always initialized first.
solid answer
~40 sConstructing a subclass always constructs the superclass part first. The compiler ensures this by requiring that the first statement of every constructor be either super(args) (an explicit parent-constructor call) or this(args) (another constructor in the same class). If you write neither, the compiler inserts an implicit no-argument super(). This produces a chain: each constructor calls up the hierarchy until Object, then bodies run top-down. A key gotcha: if the parent has no accessible no-arg constructor (because it only declares parameterized ones), the subclass must call super(args) explicitly or it won't compile. Because super()/this() must be first, you cannot reference instance fields or run logic before it. This guarantees the parent's invariants are established before the subclass adds its own state.
code
java · 14 linesclass Animal {
final String name;
Animal(String name) { this.name = name; } // only a parameterized ctor
}
class Dog extends Animal {
Dog(String name) {
super(name); // REQUIRED: no no-arg Animal() exists
// ...
}
}
// class Cat extends Animal { Cat() {} } // COMPILE ERROR:
// implicit super() has no matching Animal()go deeper
Knows super(args) calls a parent constructor and that it must come first.
Explains implicit super(), the no-arg-constructor compile error, this() vs super(), and top-down body execution.
Reasons about initialization ordering, why overridable calls in constructors are dangerous, and final-field initialization guarantees through the chain.
Designs constructor/factory strategies that keep object initialization safe and invariant-preserving across deep hierarchies, and steers teams away from fragile base-class construction patterns.
## The core guarantee: parents are built first A Java object of a subclass *contains* the state of its superclass. For the object to be valid, the superclass portion must be initialized **before** the subclass portion. Java enforces this through **constructor chaining**. ## super() — calling a parent constructor Inside a subclass constructor you may call a superclass constructor with `super(args)`. This must be the **very first statement** in the constructor body: ```java class Animal { final String name; Animal(String name) { this.name = name; } } class Dog extends Animal { Dog(String name) { super(name); // must be first // subclass-specific init follows } } ``` ## The implicit super() If you do **not** write `super(...)` or `this(...)` as the first statement, the compiler automatically inserts a call to the parent's **no-argument** constructor, `super()`. So this: ```java class Cat extends Animal { Cat() { } } ``` is treated as if you wrote `Cat() { super(); }`. ## The classic compile error The implicit `super()` only works if the parent actually *has* an accessible no-arg constructor. If `Animal` declares only `Animal(String name)` and no no-arg constructor, then `Cat() {}` fails to compile, because the inserted `super()` matches nothing. The fix is to call an existing parent constructor explicitly: `Cat() { super("unknown"); }`. (Remember: once you declare any constructor, Java no longer gives you a free default no-arg one.) ## this() vs super() The first statement can instead be `this(args)`, which delegates to **another constructor in the same class**. That constructor, in turn, must eventually reach a `super(...)`. You can use `this()` *or* `super()` as the first statement, never both — they are mutually exclusive because both must occupy the first-statement slot. ## The full chain and ordering For `new Dog("Rex")` with hierarchy `Object <- Animal <- Dog`: 1. `Dog`'s constructor calls `super(name)` → `Animal`'s constructor, 2. which (implicitly) calls `super()` → `Object`'s constructor, 3. `Object`'s body runs, 4. then `Animal`'s body runs, 5. then `Dog`'s body runs. So constructor **bodies execute top-down** (most general first), even though the calls were written bottom-up. ## Why super()/this() must be first Because the parent must be initialized before you can safely use its state, Java forbids any statement before `super()`/`this()`. You therefore cannot read instance fields or call instance methods of the object before the super call (the object isn't fully formed). (A modern refinement: recent Java versions relax this slightly to allow some preliminary statements that don't reference the instance, but the conceptual rule — parent first — stands.) ## A subtle danger: calling overridable methods from a constructor If a superclass constructor calls an overridable method, the subclass override runs **before the subclass constructor body**, so it sees uninitialized subclass fields. Avoid calling overridable methods from constructors.
- Why does Cat() {} fail to compile if Animal only has Animal(String)?The compiler inserts an implicit no-arg super(), but Animal has no no-arg constructor, so the call resolves to nothing and compilation fails. You must call super(args) explicitly.
- In what order do constructor bodies actually execute?Top-down: Object's body first, then each subclass down to the most-derived class. The super(...) calls chain upward, but the bodies unwind and run from the root downward.
- Why is calling an overridable method inside a constructor risky?Dynamic dispatch runs the subclass override while the subclass's own fields are still uninitialized, leading to nulls or wrong values.
saying these in an interview costs you the question
- Putting statements before super()/this()
- Assuming a parent always has a no-arg constructor
- Saying constructors are inherited (they are not — they chain)
- Thinking subclass body runs before the parent body
- Using both this() and super() in one constructor