Constructor Chaining

Calling constructors in inheritance

5 min read

Constructor Chaining in Java

Constructor chaining is the process of calling one constructor from another. It happens both within a class (this()) and in inheritance (super()).

Chaining Rules

  • this(): Calls another constructor in same class
  • super(): Calls parent class constructor
  • Must be the FIRST statement
  • Cannot use both this() and super() in same constructor
  • If neither specified, compiler adds super()

🔑 Execution Order: Parent constructor ALWAYS runs before child constructor. The chain goes up to Object class first, then back down.

Code Examples

Constructor chaining with super()

java
1// Constructor Chaining with super()
2class Animal {
3    protected String name;
4    
5    public Animal() {
6        System.out.println("1. Animal()");
7    }
8    
9    public Animal(String name) {
10        this.name = name;
11        System.out.println("2. Animal(String): " + name);
12    }
13}
14
15class Dog extends Animal {
16    private String breed;
17    
18    public Dog() {
19        // super() added automatically
20        System.out.println("3. Dog()");
21    }
22    
23    public Dog(String name) {
24        super(name);  // Call Animal(String)
25        System.out.println("4. Dog(String)");
26    }
27    
28    public Dog(String name, String breed) {
29        super(name);
30        this.breed = breed;
31        System.out.println("5. Dog(String, String)");
32    }
33}
34
35new Dog();
36// Output:
37// 1. Animal()
38// 3. Dog()
39
40new Dog("Buddy");
41// Output:
42// 2. Animal(String): Buddy
43// 4. Dog(String)

Constructor chaining with this()

java
1// Constructor Chaining with this()
2class Person {
3    private String name;
4    private int age;
5    private String email;
6    
7    // Primary constructor
8    public Person(String name, int age, String email) {
9        this.name = name;
10        this.age = age;
11        this.email = email;
12        System.out.println("Full constructor");
13    }
14    
15    // Chain to primary with default email
16    public Person(String name, int age) {
17        this(name, age, "no-email@example.com");
18        System.out.println("Two-arg constructor");
19    }
20    
21    // Chain with more defaults
22    public Person(String name) {
23        this(name, 0);
24        System.out.println("One-arg constructor");
25    }
26    
27    // Chain with all defaults
28    public Person() {
29        this("Unknown");
30        System.out.println("No-arg constructor");
31    }
32}
33
34new Person();
35// Output:
36// Full constructor
37// Two-arg constructor
38// One-arg constructor
39// No-arg constructor

Complete chaining pattern

java
1// Complete Chain: Both this() and super()
2class Vehicle {
3    protected String type;
4    
5    public Vehicle(String type) {
6        this.type = type;
7        System.out.println("Vehicle(" + type + ")");
8    }
9}
10
11class Car extends Vehicle {
12    private String model;
13    private int year;
14    
15    // Primary constructor calls super
16    public Car(String model, int year) {
17        super("Car");  // Must be first
18        this.model = model;
19        this.year = year;
20        System.out.println("Car(model, year)");
21    }
22    
23    // Secondary constructor chains to primary
24    public Car(String model) {
25        this(model, 2024);  // Calls Car(String, int)
26        System.out.println("Car(model)");
27    }
28    
29    // Another constructor
30    public Car() {
31        this("Unknown");  // Calls Car(String)
32        System.out.println("Car()");
33    }
34}
35
36new Car();
37// Output:
38// Vehicle(Car)         ← super() called from primary
39// Car(model, year)     ← primary constructor
40// Car(model)           ← secondary
41// Car()                ← called constructor

Multilevel chaining and common errors

java
1// Multilevel Constructor Chaining
2class GrandParent {
3    public GrandParent() {
4        System.out.println("1. GrandParent constructor");
5    }
6}
7
8class Parent extends GrandParent {
9    public Parent() {
10        // super() automatically inserted
11        System.out.println("2. Parent constructor");
12    }
13}
14
15class Child extends Parent {
16    public Child() {
17        // super() automatically inserted
18        System.out.println("3. Child constructor");
19    }
20}
21
22new Child();
23// Output:
24// 1. GrandParent constructor
25// 2. Parent constructor
26// 3. Child constructor
27
28// Order: Goes UP the chain first, then executes DOWN
29// Compiler adds: Object() → GrandParent() → Parent() → Child()
30
31// Common Error: No default constructor in parent
32class BadParent {
33    public BadParent(String name) {}  // No no-arg constructor
34}
35
36// class BadChild extends BadParent {}  // ERROR!
37// Because compiler tries to call super() but BadParent has no no-arg
38
39class GoodChild extends BadParent {
40    public GoodChild() {
41        super("default");  // Must explicitly call available constructor
42    }
43}

Use Cases

  • Reducing constructor code duplication
  • Providing constructor overloads
  • Initializing parent class state
  • Builder pattern initialization
  • Default value handling
  • Validation in single place

Common Mistakes to Avoid

  • Forgetting super()/this() must be first
  • Trying to use both this() and super()
  • Circular constructor calls
  • Not providing required super() call
  • Calling methods before super completes
  • Not understanding execution order