Javasuper关键字的使用场景与核心概念

super()必须位于子类构造方法首行,否则编译失败;不写则编译器自动插入无参super(),但父类须有无参构造;若父类仅有带参构造,子类必须显式调用super(…)且仅一次;super.用于访问被隐藏的父类成员(非private),super.method()可绕过重写调用父类实现;super不可在static上下文中使用。

super() 必须是构造方法第一行调用

子类构造方法中,如果要显式调用父类构造方法,super() 必须出现在第一行,否则编译失败。Java 不允许在执行任何其他语句(包括变量声明、if 判断、日志打印)后再调用 super()

  • 不写 super() 时,编译器会自动插入无参的 super() —— 但前提是父类有无参构造方法;否则直接报错 Constructor not defined
  • 若父类只有带参构造方法(比如 Parent(String name)),子类构造方法必须显式写 super("xxx"),且只能写一次
  • this()super() 不能共存于同一个构造方法中——二者都必须是首行,冲突

super. 用于访问被子类隐藏的父类成员

当子类定义了与父类同名的字段或方法(非重写,而是隐藏或重载),用 super.fieldNamesuper.methodName() 可明确访问父类版本。注意:这不适用于 private 成员,它们不可见。

  • 字段隐藏(field hiding)常见于子类定义了同名 public/protected 字段;此时 super.name 是唯一安全读取父类字段的方式
  • 方法调用中,super.method() 强制调用父类实现,绕过子类重写逻辑——适合模板方法模式中“钩子回调”场景
  • 静态方法也能用 super.staticMethod() 调用,但实际是编译期绑定父类类型,和运行时无关
class Parent {
    protected String type = "parent";
    public void print() { System.out.println("Parent.print"); }
}
class Child extends Parent {
    protected String type = "child"; // 隐藏父类字段
    @Ove

rride public void print() { System.out.println("Child.print"); } public void show() { System.out.println(super.type); // 输出 "parent" super.print(); // 输出 "Parent.print" } }

super 在重写方法中调用父类逻辑

这是最常见也最易出错的使用点:子类重写方法后,需要复用父类部分行为(如初始化、校验、清理),就用 super.methodName() 显式委托。漏掉它,可能破坏父类契约。

  • 典型场景:重写 toString()equals(Object)hashCode() 时,应先调用 super.toString() 拼接父类字段信息
  • 重写生命周期方法(如 Android 的 onCreate()、Swing 的 paintComponent())几乎必须先调用 super.xxx(),否则 UI 或状态机异常
  • 错误写法:if (valid) super.save(); else throw ... —— 看似合理,但若父类 save() 有前置初始化逻辑,跳过会导致 NPE 或状态不一致

super 不能在 static 上下文中使用

super 是实例相关关键字,代表当前对象的父类视图,因此绝不能出现在 static 方法、static 块或 static 字段初始化表达式中。编译器会直接报错 non-static variable super cannot be referenced from a static context

  • 常见误操作:在 public static void main(String[] args) 里写 super.toString() —— 不合法,因为没有隐式 this
  • 替代方案:若需复用父类静态逻辑,应通过类名直接调用,如 Parent.doInit(),而非依赖 super
  • 内部类中也要小心:静态嵌套类(static class Nested)里也不能用 super,哪怕它位于继承链中
父类字段是否被 private 修饰、构造方法是否可访问、当前上下文是否为实例方法——这三个条件共同决定 super 能否用、怎么用。漏判任一条件,编译错误或运行时行为异常就很难避免。