super是java中访问父类成员的关键字,主要用于两类场景:一是子类构造器首行显式调用父类构造器(如super(...)),二是用super.变量名访问被子类同名实例变量遮蔽的父类成员;不能用于private成员或static上下文。

super 是 Java 中用于显式访问父类成员的关键字,实战中主要用在两类场景:调用父类构造器(必须是子类构造器的第一条语句),以及访问被子类同名成员变量或方法覆盖的父类版本。下面结合常见误区和实际写法,讲清楚怎么用、为什么这么用。
调用父类构造器:必须放在第一行,且只能出现一次
子类构造器默认会隐式调用 super()(无参父类构造器)。一旦父类没有无参构造器,或你想传参初始化父类状态,就必须显式写出 super(...),且它必须是子类构造器的第一条语句。
- 错误写法:先声明变量、调用 this()、或加 if 判断后再写 super → 编译不通过
- 正确写法示例:
class Animal {
String name;
Animal(String name) { this.name = name; }
}
class Dog extends Animal {
int age;
Dog(String name, int age) {
super(name); // ✅ 必须第一行,把 name 传给父类初始化
this.age = age;
}
}
访问被覆盖的父类成员变量:用 super.变量名,避开子类同名遮蔽
当子类定义了与父类同名的实例变量(注意:不是重写,是遮蔽 / hiding),直接写变量名会访问子类自己的;想读取父类那份原始值,就得用 super.变量名。
- 仅适用于实例变量(非 static);static 变量用 父类名.变量名 更清晰,super 访问静态成员不推荐
- 常见于调试或特殊逻辑,比如记录父类初始状态
class Parent {
String id = "P001";
}
class Child extends Parent {
String id = "C002"; // 遮蔽了父类 id
void printIds() {
System.out.println("子类id: " + id); // 输出 C002
System.out.println("父类id: " + super.id); // 输出 P001
}
}
区分 super 和 this:别混淆“调用父类”和“调用本类其他构造器”
super(...) 调用父类构造器,this(...) 调用本类其他构造器,二者互斥——一个构造器里只能出现其中一种,且都必须是首行。
- 想复用本类多个构造逻辑?用 this(...) 委托,再由最终那个构造器调用 super(...)
- 误写成 super() 和 this() 都出现 → 编译报错
不适用场景提醒:super 不能访问 private 成员,也不能在 static 上下文中使用
父类 private 字段/方法对子类不可见,super 也无法穿透访问;同样,static 方法或静态代码块中没有“当前对象”,super 没有意义,编译直接拒绝。
- 替代方案:父类提供 protected 或 public 的 getter 方法供子类间接访问 private 状态
- 静态工具方法需要父类数据?应设计为参数传入,而非依赖 super










