Java继承中this为何指向子类且访问到不同的成员变量?
代码运行结果原理解析
疑问1:为什么两次打印this都是同一个Index2实例,而非Test实例?
Java执行new Index2()时,只会在堆上创建一个对象,不会分别生成独立的Test实例和Index2实例。这个单一对象内部会同时持有父类Test、子类Index2定义的所有成员,仅在逻辑上区分为父类部分、子类部分,根本不存在可独立存在的Test类实例。
而this的含义是当前正在执行的方法所属的对象引用:从最开始的new Index2().method(),到后续调用super.method(),整条方法调用链的载体都是这同一个Index2对象,不存在中途切换对象的情况,因此两次打印的this哈希值完全一致。
疑问2:同一个对象,为什么第一次打印this.name得到"a",调用super.method后得到"b"?
核心原因是:Java的成员变量没有多态特性,子类和父类定义同名成员变量时,只会发生字段隐藏,不会动态覆盖。
这个单一的Index2对象里,实际上存了两个独立的、都叫name的字段:
- 来自父类Test的
name,初始值为"b" - 来自子类Index2的
name,初始值为"a"
访问成员变量时是静态绑定的,完全看写这行代码时所在的类的作用域:
- 在Index2类的method中写
this.name,作用域属于Index2,因此优先访问Index2自己定义的name字段,拿到值"a" - 调用
super.method()进入Test类的method代码后,作用域属于Test,因此这里的this.name只会访问Test自己定义的name字段,拿到值"b"
整个过程中没有修改任何字段的值,只是访问了两个不同的同名字段而已。
疑问3:为什么父类Test的method中的this指向Index2实例,而非Test类实例?
super.method()的本质,是让当前的Index2实例执行父类定义的method逻辑,并不是把对象切换成Test实例、再执行方法。
Java的this引用永远指向发起本次方法调用的原始对象,不会因为方法逻辑写在父类代码里,就自动把this指向所谓的“父类部分”。从最开始调用Index2对象的method开始,整个执行链路的载体都是这同一个Index2对象,父类method只是被这个对象调用的一段逻辑,自然this指向的还是原来的Index2实例。
内容的提问来源于stack exchange,提问作者alalalala
相关产品推荐
相关产品推荐

