this不能调用父类构造方法,因为this()仅用于当前类构造重载跳转,而super()才是显式委托父类初始化;JVM要求每个构造器必须最终调用Object构造器,且禁止绕过当前类自身初始化流程。

为什么 this 不能调用父类构造方法,而 super() 可以
this() 和 super() 都只能出现在构造方法的第一行,但语义完全不同:super() 是显式委托父类构造逻辑,而 this() 是当前类内部的构造重载跳转。JVM 规定:每个构造方法必须且只能通过一条路径最终调用到 java.lang.Object 的构造器;如果允许 this() 调父类构造,就等于绕过当前类自己的初始化流程,破坏对象创建契约。
-
super()是编译器生成的对父类方法的直接调用,目标是完成父类字段初始化 -
this()编译后仍是当前类的另一个,它仍需自己处理父类部分——最终仍要调一次super() - 若在子类构造中既写
this()又写super(),编译器直接报错:call to this() must be first statement in constructor
this 和 super 在方法调用中的绑定时机不同
this 指向当前运行时对象,其方法调用走的是虚方法表(vtable)动态分派;super 是语法糖,强制走**编译期确定的父类版本**,不经过动态绑定。哪怕子类重写了该方法,super.method() 也永远调用父类原始实现。
- 使用
super.method()时,字节码里是invokespecial指令,不是invokevirtual -
this.method()在非private/static/final方法上,实际执行的是子类覆写的版本 - 注意陷阱:在父类构造器中调用
this.method(),若该方法被子类重写,会触发子类方法——但此时子类字段尚未初始化(值为默认值),极易引发NullPointerException或逻辑错误
this 可作引用传递,super 不能当对象使用
this 是一个合法的引用表达式,可以赋值给变量、作为参数传入、甚至返回;super 不是对象,也不是引用类型,它只是访问父类成员的限定符,不能单独存在。
- 下面代码合法:
public void foo() { bar(this); } - 下面代码非法:
public void foo() { bar(super); } // 编译错误:not a statement -
super后面必须紧跟点号和成员名,如super.toString()、super.fieldName - 试图把
super强转成某个类型(如(Parent) super)也会编译失败
字段访问时 this.field 和 super.field 的实际效果可能一样
当子类没有定义同名字段时,this.field 和 super.field 最终都指向父类声明的那个字段——因为 Java 中字段不支持多态,不存在“重写字段”的概念,只有隐藏(hiding)。但如果子类定义了同名字段,两者就明确分离。
立即学习“Java免费学习笔记(深入)”;
- 父类有
protected int x = 1;,子类无x字段 →this.x和super.x都读取同一个内存位置 - 子类加了
int x = 2;→this.x读子类字段,super.x读父类字段(两个独立存储) - 这种字段隐藏容易导致混淆,建议避免在子类中用相同名字重新声明继承来的字段
this 和 super 看似简单,但它们背后连着字节码指令选择、类加载顺序、字段存储模型这些底层细节。最容易出问题的地方不在语法书写,而在构造器中误用 this 触发未初始化的方法,或在字段同名时误以为 super.field 是“安全访问”,结果读到了意料之外的值。










