在Java继承体系里,每当使用new创建子类对象,系统都会先从最顶层的父类开始执行构造器,再逐层往下,直到子类自身构造器结束,这条隐式的调用路径就是构造器链。子类构造器无论写不写super(),编译器都会优先保证父类被初始化。

构造器链的默认行为
如果子类构造器没有显式调用super(),编译器会自动插入一个无参的super()。这就要求父类必须存在可访问的无参构造器,否则代码无法通过编译。
class Parent {
Parent() {
System.out.println("父类无参构造器");
}
}
class Child extends Parent {
Child() {
// 编译器自动插入 super();
System.out.println("子类构造器");
}
}
public class Test {
public static void main(String[] args) {
new Child();
}
}
父类没有无参构造器怎么办
当父类只定义了带参数的构造器,无参构造器就不存在了。此时子类必须显式使用super(实参)调用父类构造器,并且这行代码必须是子类构造器的第一条语句。
class Parent {
Parent(String name) {
System.out.println("父类构造器,name=" + name);
}
}
class Child extends Parent {
Child() {
super("默认名称"); // 必须显式调用,且为第一行
System.out.println("子类构造器");
}
}
常见错误与规则说明
- 在构造器里把super()写在普通代码之后,会报语法错误。
- 如果父类有多个构造器,子类可根据需要选择其中一个super(...)版本。
- this()和super()不能同时出现在同一个构造器中,因为二者都要求位于第一行。
构造器链的执行顺序示例
下面例子展示了多层继承时构造器链的真实执行过程:
class Grandpa {
Grandpa() {
System.out.println("祖父构造器");
}
}
class Parent extends Grandpa {
Parent() {
super();
System.out.println("父亲构造器");
}
}
class Child extends Parent {
Child() {
super();
System.out.println("孩子构造器");
}
}
public class Demo {
public static void main(String[] args) {
new Child();
}
}
运行后输出依次为祖父构造器、父亲构造器、孩子构造器,证明构造器链自顶层父类向下推进。掌握这一点,就能合理设计父类构造器,并在子类中正确传入初始化参数,避免对象状态异常。