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

Java子类重写方法的参数传递与执行副作用问题解析

解析Java子类方法调用中的参数传递与执行逻辑

咱们一步一步拆解这段代码的执行过程,就能搞清楚参数怎么传递、方法调用的逻辑,还有为啥最后输出是0了。

一、子类B的setX方法参数传递路径

当执行new B()创建对象时,参数的传递是这样走的:

  1. 首先进入父类A的构造器,构造器里的setX(x-3)中,这里的x是父类A的实例变量,初始值是3,所以计算得出3-3=0,这个0就是要传递的参数。
  2. 由于Java的动态绑定机制(多态),此时实际创建的是B对象,所以会调用子类B重写的setX方法,这个0就被传递给了B的setX方法的参数z。

二、完整的方法调用执行逻辑

按代码执行的先后顺序梳理:

  • 第一步:执行A ab = new B();,触发B的实例化。Java规定子类构造器默认会先调用父类的无参构造器,所以先进入A的构造方法。
  • 第二步:在A的构造器中执行setX(x-3):
    • 这里的x是A类的实例变量,值为3,计算后得到参数值0。
    • 因为当前对象的实际类型是B,所以调用的是B类中重写的setX方法,而不是A自己的setX方法。
  • 第三步:进入B的setX(int z)方法:
    • 参数z接收的就是从父类构造器传过来的0。
    • 方法里的x = z,这里的x是B类的静态变量(B类定义的是static int x=7),所以直接把B的静态x的值改成了0。
  • 第四步:父类构造器执行完成后,回到B的默认构造器(B没有显式写构造器,所以用默认的空构造),对象创建完成。
  • 第五步:执行System.out.println(B.x),输出的是B类的静态变量x,此时它的值已经被改成0,所以最终输出0。

三、执行过程中的副作用与注意点

  • 父类构造调用子类重写方法的风险:这是Java里一个容易踩坑的点!父类构造器执行时,子类的实例初始化还没完成(如果子类有实例变量的话),此时调用子类重写的方法,可能会访问到未初始化的子类实例变量,导致奇怪的错误。这里还好是修改静态变量,但依然属于意外修改了子类的状态。
  • 变量命名混淆的坑:这里A的x是实例变量,B的x是静态变量,两者是完全独立的变量。新手很容易把它们搞混,误以为是同一个变量被修改,其实是两个不同的东西。
  • 静态变量的全局影响:B的静态变量x属于类本身,所有B的对象都会共享这个值,这次父类构造器的调用直接修改了这个全局静态值,导致后续所有访问B.x的地方都会拿到修改后的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:32:43