🧬 Inheritance & Polymorphism · Intermediate

Constructor order in hierarchies in Java

Parent constructor runs before child; implicit super().

🧩 The mysteryYou build a house foundation first, then walls, then the roof. Java builds objects in exactly the same order — whether you ask it to or not.

Top-down construction

Every constructor starts by calling a parent constructor (an implicit super() if you write none). That call goes up and up, all the way to Object. Then the bodies run on the way back down: most general first, most specific last.

🔮 Predict it

Three generations

What does new Z() print?

class X { X() { System.out.print("X"); } }
class Y extends X {
    Y() { System.out.print("Y"); }
}
class Z extends Y {
    Z() { System.out.print("Z"); }
}
void main() { new Z(); }
  1. Z
  2. ZYX
  3. XYZ
  4. YZ
Show the answer

XYZ. Z() implicitly starts with super(), which runs Y(), which runs X(). Each body prints only after its parent's constructor has returned.

The exact order

For one new Kid(): 1. the parent constructor runs completely; 2. Kid's field initializers (and instance blocks) run; 3. Kid's constructor body runs. Fields are initialized *after* the parent is done.

🔮 Predict it

Where do the fields fit?

What does this print?

class P { P() { System.out.print("P "); } }
class K extends P {
    int x = log("init ");
    K() { System.out.print("K"); }
    int log(String s) {
        System.out.print(s); return 0;
    }
}
void main() { new K(); }
  1. init P K
  2. P init K
  3. P K init
Show the answer

P init K. First the implicit super() runs P(). Then K's field initializer runs, and finally K's constructor body.

Java 25: code before super(...)

Java 25's flexible constructor bodies (JEP 513) allow statements before super(...). They run first — even before the parent constructor — so they can validate arguments. They just can't use the half-built object.

class K extends P {
    K() {
        System.out.print("pre ");
        super();
        System.out.print("K");
    }
}
// new K() prints: pre P K
⚠️ The trap

A parent without a no-arg constructor

The hidden super() needs a no-arg parent constructor. If the parent only has P(String), every child constructor must call super(...) explicitly — otherwise: compile error.

class P { P(String s) { } }
class K extends P {
    K() { }  // error: no P()
}
💼 In the real world

In real projects

Heavy work in a base-class constructor slows down every subclass. And before Java 25, validating a subclass argument meant running the parent constructor first — even with bad input. Prologue code before super(...) lets you fail fast.

Key takeaways

  1. Parent constructor finishes before the child's body
  2. Child field initializers run right after super() returns
  3. Implicit super() is inserted when you write none
  4. Java 25: code before super(...) runs even earlier
🤯 Did you know?

Even Object has a constructor. Every object you've ever created ran Object() at the very top of its constructor chain.

Practice questions

What does this print?

class A { A() { System.out.print("A"); } }
class B extends A {
    B() { System.out.print("B"); }
}
class C extends B {
    C() { System.out.print("C"); }
}
void main() { new C(); }
  1. C
  2. CBA
  3. ABC
  4. BC
Check your answer

ABC. C() implicitly starts with super(), which runs B(), which runs A(). Each body prints after its parent's constructor returns.

What does this print?

class P { P() { System.out.print("P "); } }
class K extends P {
    int x = log("field ");
    K() { System.out.print("K"); }
    int log(String s) {
        System.out.print(s);
        return 1;
    }
}
void main() { new K(); }
  1. field P K
  2. P field K
  3. P K field
  4. K P field
Check your answer

P field K. First the implicit super() runs P(). Then K's field initializers run, and finally K's constructor body.

Next: replacing a parent's method — and the four promises an override must keep.