super并非调用父类对象,而是访问当前子类实例中继承自父类的内存区域;字段访问编译期绑定、不参与多态,方法调用则绕过重写执行父类版本;super()必须首行且与this()互斥;命名冲突易致null值,应避免同名字段。

super不是“调用父类”,而是访问当前对象的父类部分
很多人误以为 super 是在创建或引用一个独立的父类对象,其实完全不是——它只是指向**当前子类实例中继承自父类的那一块内存区域**。比如 Student s = new Student("张三", 101),super.name 访问的不是另一个 Person 对象,而是 s 自身里从 Person 继承来的 name 字段。
这个理解直接影响你对字段访问和方法调用行为的判断:
- 字段访问(如
super.name)在编译期就绑定到父类声明,不参与多态,哪怕子类重写了同名字段也互不影响 - 方法调用(如
super.move())才真正“绕过”子类重写,强制执行父类版本,这是运行时确定的 -
private字段/方法永远无法被super访问,因为继承关系不覆盖访问控制
super() 必须放在构造方法第一行,且不能和 this() 共存
这是 Java 编译器强制的语法铁律。如果你写:
Student(String name, int id) {
this.id = id;
super(name); // ❌ 编译报错:非法位置
}
就会直接失败。原因很实在:对象初始化必须先完成父类部分,再填充子类特有字段——就像盖楼,地基(父类状态)没打好,楼上(子类字段)没法安全施工。
立即学习“Java免费学习笔记(深入)”;
实操建议:
- 如果父类只有带参构造,子类所有构造方法都必须显式写
super(...),否则编译不过 - 若父类没定义任何构造方法,Java 会自动提供无参
super();但只要父类写了任意构造方法,这个默认无参构造就消失了 - 想复用子类自身其他构造逻辑?用
this(...),但它和super(...)是互斥的,二选一
super 访问字段和方法时,命名冲突是典型踩坑点
当子类和父类都有同名字段(比如都叫 name),不加 super 默认访问的是子类自己的;但很多人以为 super.name 是“取父类值”,却忘了父类字段可能根本没初始化。
看这个常见错误:
class Person { String name; }
class Student extends Person {
String name = "学生A";
void print() {
System.out.println(super.name); // 输出 null!因为父类构造没设值
System.out.println(this.name); // 输出 "学生A"
}
}
所以关键不是“能不能用 super”,而是“父类那部分有没有被正确初始化”。解决办法:
- 优先在父类构造中初始化字段,而不是依赖子类赋值
- 避免在父子类中声明同名字段——这不是多态,只是隐藏,极易引发逻辑混乱
- 如果真要区分,用不同名(如
parentName/studentName),比靠super更清晰
super 和 this 的本质区别:一个指“父类部分”,一个指“当前完整对象”
this 是当前对象的完整引用,能调用所有可见方法、访问所有可见字段;super 只是一个受限视图,仅用于明确切入父类上下文。
比如你在子类里写 this.toString(),走的是子类重写的版本;而 super.toString() 强制走父类原始实现。但注意:super 不能用于转型((Parent)this 合法,(Parent)super 不合法),也不能作为方法参数传递(someMethod(super) 编译失败)。
最容易被忽略的一点:当你在子类静态方法里试图用 super,会直接编译报错——因为 super 依赖实例上下文,而静态方法没有“当前对象”。








