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

继承机制疑问:初始化子类A对象时将调用哪个doSomething方法?

子类初始化时父类构造调用重写方法的执行逻辑

先给你明确结论:此时执行的是A中重写后的doSomething实现,下面给你拆解整个过程和背后的原因:

首先把你给出的代码整理成更易读的形式:

类B的定义:

public class B {
    public B(){
        doSomething();
    }
    public void doSomething(){
        // B类的实现逻辑
    }
}

类A的定义:

class A extends B {
    public A() {
        super(); // 这行其实可以省略,Java默认会自动调用父类无参构造
    }

    @Override
    public void doSomething(){
        // A类重写后的实现逻辑
    }
}

执行过程拆解

当你执行new A()创建A的实例时,整个流程是这样的:

  1. 进入A的构造函数,首先会调用父类B的构造函数(不管你写不写super(),Java都会默认在子类构造的第一行插入这行代码)。
  2. 进入B的构造函数,执行到doSomething()调用。
  3. 这里的关键:Java的方法调用是动态绑定的——它会根据当前对象的实际类型来选择要执行的方法。此时虽然我们正在执行B的构造函数,但当前正在创建的对象本质上是A的实例,所以会找到A中重写的doSomething方法并执行。
  4. 等B的构造函数执行完,才会回到A的构造函数继续执行剩余逻辑。

重要提醒

这个场景其实是一个常见的坑:因为父类构造执行时,子类的成员变量还没有完成初始化(子类构造的逻辑在父类构造之后才会执行)。如果A的doSomething方法里用到了A自己的成员变量,很可能会拿到未初始化的默认值(比如int是0,对象是null),导致不可预期的错误。

所以在Java开发中,尽量不要在父类的构造函数里调用可被重写的方法,这是一种不良的编码实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:08:22