Java继承中this关键字调用方法疑问:为何触发子类重写方法?
Java继承中方法调用与成员变量访问的差异解析
先看你给出的代码:
class A { int n; public A() { this.n = 1; } public void compute() { this.n = this.n * 2; } public void print() { this.compute(); System.out.println("A: " + this.n); } public static void main(String[] args) { B b = new B(); b.print(); } } class B extends A { int n; public B() { this.n = 5; } public void compute() { this.n = this.n * 2; } public void print() { super.print(); System.out.println("B: " + this.n); } }
这个现象的核心原因是Java中方法调用的动态绑定,和成员变量访问的静态绑定规则不同,具体拆解如下:
1. 方法调用:动态绑定(运行时多态)
Java中,所有非静态的成员方法调用,都是基于对象的实际类型来确定的,而非引用的声明类型。
- 当
b.print()执行时,进入B类的print方法,调用super.print()进入A类的print方法。 - 在A类的
print里执行this.compute(),这里的this指向的是实际创建的B类对象(而非A类对象),所以会调用B类中重写的compute方法,把B类自己的n从5改成10。
2. 成员变量访问:静态绑定(编译时确定)
成员变量不存在“重写”的概念,子类的同名变量只是隐藏了父类的变量,两者是独立的存储空间。
- A类的
print方法里的this.n,在编译阶段就已经确定是A类定义的n——因为这段代码写在A类中,编译器只会识别当前类的成员变量。 - 所以即使
this实际指向B对象,这里打印的依然是A类的n(值为1,由A的构造函数初始化后未被修改过)。
完整执行流程验证
- 创建B对象时,先执行父类A的构造函数,A的
n被设为1;再执行B的构造函数,B的n被设为5。 - 调用
b.print()进入B的print,执行super.print()进入A的print。 - A的
print调用this.compute(),实际执行B的compute,B的n变为10。 - A的
print打印A: 1(A类的n始终是1)。 - 回到B的
print,打印B: 10(B类的n已经被修改为10)。
内容的提问来源于stack exchange,提问作者231_koh
相关产品推荐
相关产品推荐

