What is the order of constructor calls when you create an instance of a subclass, and why is it fixed?
The order is fixed by the language, not by your code. When you evaluate new ElectricCar, the runtime allocates the object, gives the instance fields their default values, runs the field initialisers and any initialiser blocks of the subclass, then runs the parent constructor, and finally runs the subclass constructor body.
public class Main {
public static void main(String[] args) {
new ElectricCar("model-3", 500);
}
}
class Car {
protected final String model;
Car(String model) {
this.model = model;
System.out.println("car: " + model);
}
}
class ElectricCar extends Car {
private final int range;
ElectricCar(String model, int range) {
super(model);
this.range = range;
System.out.println("electric: " + model + " range " + range);
}
}The output makes the sequence visible. The car constructor runs first and prints its message, and only then does the electric car constructor run and print its own. The subclass body could not have run earlier, because it assigns to an inherited final field, and that field is only set by the parent constructor.
This is why the super call has to be the first statement of the constructor. The parent state must exist before the subclass can rely on it, and the language enforces the ordering rather than trusting you to remember it.
One more consequence worth mentioning: if a parent constructor calls an overridden method, the subclass version runs at that point, before the subclass's own fields are initialised. That is the classic surprise, and the usual workaround is to avoid calling overridable methods from constructors.