当父类无无参构造器时,子类构造器首行必须显式调用super(参数),因编译器不再自动生成无参构造器,且JVM要求父类字段必须在子类执行前由其构造器初始化。

当父类没有无参构造器时,子类构造器必须在第一行显式写 super(参数),这不是编码习惯,而是 Java 编译器强制执行的对象初始化规则。
父类无参构造器消失的真相
Java 编译器只在类中**完全没定义任何构造器**时,才自动补一个 public 的无参构造器。一旦你写了任意一个带参构造器(比如 public Person(String name)),默认无参构造器就立刻消失——它不会“并存”,也不会“退居二线”。子类看不到、也调用不了那个不存在的无参构造器。
- 父类只写
public Animal(String name, int age)→ 无参构造器被抹除 - 子类若不写
super(name, age),编译器尝试插入super()就会失败 - 报错信息直白:“Implicit super constructor Animal() is undefined”
为什么必须是第一行且不能省略
子类对象内存布局里包含父类字段空间,这些字段(哪怕 private 或 final)只能由父类自己的构造器来赋值。JVM 要求:父类部分必须在子类代码执行前就初始化完毕,否则访问 this.name 可能拿到 null 或 0,逻辑就崩了。
-
super(...)是启动父类初始化的唯一合法入口 - 它必须是首句,防止子类提前读写未初始化的父类字段
- 不写就是编译失败,不是运行时报错——Java 把风险挡在编译期
怎么写才合法
显式调用的 super(...) 必须严格匹配父类某个构造器的签名:参数类型、个数、顺序全对。
立即学习“Java免费学习笔记(深入)”;
- 父类有
public Car(String brand, double price) - 子类可写
super("Toyota", 25000.0)✅ - 但不能写
super("Toyota")(少参数)或super(25000.0, "Toyota")(顺序错)❌ - 也不能和
this(...)共存——二者都抢首行,语法上冲突
常见误区澄清
有人以为“我子类没动父类字段,所以不用管父类构造”,这是错的。即使子类什么都没用到,父类构造器可能在做关键事:校验参数、初始化 final 字段、注册监听、分配资源……跳过它,对象就不完整。
-
super不是调用普通方法,是触发父类初始化阶段 - private 字段虽不可见,但属于对象状态的一部分,靠父类构造器设置
- 多层继承中,子类只负责调直接父类;祖父类是否被正确初始化,由父类自己保证


















