super()必须是子类构造器第一句,否则编译报错;它严格按实参匹配父类可见构造器,不可在普通方法或静态上下文中使用。

super() 必须是子类构造器的第一条语句
Java 规定,只要在子类构造器中显式调用 super()(或 this()),它必须出现在第一行。否则编译直接报错:error: call to super must be first statement in constructor。这不是风格问题,是语法硬性限制。
常见误操作是先做变量赋值、日志打印或条件判断再调用 super()——这些都会导致编译失败。
- ✅ 正确写法:
super(name, age);紧贴构造器开头 - ❌ 错误写法:
System.out.println("init"); super(name, age); - ⚠️ 注意:哪怕只调用无参
super(),也必须显式写出(如果父类没提供默认无参构造器)
调用父类哪个构造器,取决于参数类型和数量
super(...) 不是“选一个父类构造器”,而是由你传入的实参列表**精确匹配**父类中某个 public / protected / 包级可见的构造器签名。编译器按重载解析规则匹配,不自动转型(除非是基本类型拓宽,如 int → long)。
例如父类有:Parent(String name) 和 Parent(int id),那么:
-
super("Alice")→ 匹配String版本 -
super(123)→ 匹配int版本 -
super(null)→ 编译失败(歧义:String和int都不接受null) -
super((String) null)→ 显式强制类型,可解歧义
父类没有匹配构造器时,编译直接失败
如果父类只定义了带参构造器(比如只有 Parent(String name, int age)),而子类构造器里写的是 super()(无参),就会报错:constructor Parent in class Parent cannot be applied to given types。
此时不能靠“Java 默认插入无参 super()”来蒙混——那个默认行为只在子类构造器**完全没写任何 super 或 this** 时才生效,且前提是父类**恰好存在无参构造器**。
- ✅ 安全做法:父类提供无参构造器,或子类明确传参调用存在的构造器
- ❌ 依赖“父类应该有无参构造器”这种假设,容易在继承链变长时崩塌
- ? 提示:IDE(如 IntelliJ)通常会在父类构造器被删后,立刻标红子类中所有
super()调用
不能在普通方法或静态上下文中使用 super()
super() 是构造器专用语法,只允许出现在构造器第一行。试图在 static 方法、实例方法、lambda 或初始化块里写它,会触发编译错误:call to super must be first statement in constructor(即使位置对,上下文也不合法)。
如果你需要复用父类某段初始化逻辑,但又不在构造器里——那它本来就不该是构造逻辑,应提取为普通 protected 方法,由子类按需调用。
- ❌
void init() { super("test"); }→ 语法非法 - ✅
protected void initParentFields(String name) { this.name = name; }→ 可行 - ⚠️ 注意:
super()调用的是父类构造器,不是普通方法;它完成的是对象实例的“诞生仪式”,不可拆分复用
真正容易被忽略的点在于:super() 的匹配发生在编译期,且严格依赖父类构造器的可见性与签名。一旦父类 jar 升级、构造器被改名或加了 private,你的子类可能在毫无征兆的情况下编译不过——连运行都到不了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











