You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java继承代码输出分析:变量遮蔽与方法调用疑问

详解Java继承代码的输出逻辑(变量遮蔽+构造执行顺序)

咱们一步步拆解这段代码的执行过程,把你标注的两个疑问和每一行输出都讲透——核心要区分方法重写和**变量遮蔽(Variable Shadowing)**的本质区别,还要牢记Java子类对象创建的初始化顺序。

先明确两个关键知识点:

  • 变量没有“重写”概念:子类的num只是遮蔽了父类的num,二者是完全独立的实例变量,存放在不同内存区域;只有方法才会被重写。
  • 子类对象创建的固定顺序:当执行new Child()时,JVM会先完成父类的实例初始化,再处理子类部分,具体流程是:
    父类实例代码块 → 父类构造器 → 子类实例代码块 → 子类构造器

接下来逐行对应输出分析:

1. 父类实例代码块执行

{ // 父类代码块
 System.out.println("Parent constructor code..."+num);
}

输出:Parent constructor code...9

  • 此时父类的实例变量num已经完成初始化(值为9),父类代码块只会访问自己类的成员变量,和子类的num毫无关系——这就是变量遮蔽的特点:父类代码不会“看到”子类的同名变量,所以输出9。你之前认为的“重写”是误解,变量不存在重写,只有方法才有。

2. 父类构造器执行

首先输出构造器第一行:Parent constructor run
然后执行show();,这里调用的是子类的show()方法,原因是多态的动态绑定:

  • 虽然这段代码写在父类构造器里,但此时正在创建的是Child对象,JVM会根据对象的实际类型(而非引用类型)调用方法。父类的show()已经被子类重写,所以会执行子类的show()实现。

那为什么子类show()输出Child show...0?

  • 此时子类的实例变量num还没完成初始化!子类的实例代码块和构造器都还没执行,子类的num处于默认初始化状态(int类型默认值为0),而子类show()访问的是自己的num(变量遮蔽),所以输出0。

3. 子类实例代码块执行

{ 
 System.out.println("Child constructor code..."+num);
 num = 10;
}

输出:Child constructor code...8

  • 父类初始化完成后,JVM开始初始化子类的实例变量:先把子类num赋值为8,然后执行实例代码块,输出此时的num(8),接着把num修改为10。

4. 子类构造器执行

首先输出:Child constructor run
然后执行show();,此时子类的num已经被实例代码块改成10了,所以子类show()输出Child show...10。

最后再明确你的两个疑问:

  1. 为什么首行num是9?
    • 父类代码块访问的是自身的num,和子类num是独立变量,不存在重写,此时父类num已初始化完成,所以输出9。
  2. 父类构造器里的show()为何调用子类的?
    • 这是Java多态的动态绑定特性:调用实例方法时,JVM会根据当前对象的实际类型(这里是Child)调用对应的重写方法,哪怕调用发生在父类构造器中。

内容的提问来源于stack exchange,提问作者sunyanL1236

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:59:09