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

Java子类构造执行时为何首次输出为0 teamlead而非2 teamlead?

class Test {

    public static void main(String[] args) {
        new TeamLead(1);
    }

    public static class TeamLead extends Programmer {

        private int numTeamLead=2;

        public TeamLead(int numTeamLead) {
            super(numTeamLead);
            this.numTeamLead = numTeamLead;
            employ();
        }

        protected void employ() {
            System.out.println(numTeamLead + " teamlead");
        }

    }

    public static class Programmer {

        private final int numProgrammer;

        public Programmer(int numProgrammer) {
            this.numProgrammer = numProgrammer;
            employ();
        }

        protected void employ() {
            System.out.println(numProgrammer + " programmer");
        }
    }
}

问题

为何首次输出是0 teamlead而非2 teamlead?

我在执行employ()前已声明numTeamLead=2,但首次执行employ()时,numTeamLead却默认值为0。我知道super(numTeamLead)会调用TeamLead.employ()而非Programmer.employ(),但为何此时numTeamLead是0而非预先初始化的值?

解答

核心原因是Java子类对象的初始化顺序规则:

  • 调用子类构造器时,第一步必须执行父类构造器(也就是代码里的super(numTeamLead))
  • 父类构造器执行过程中调用了employ(),由于子类重写了这个方法,实际执行的是子类TeamLead的employ()
  • 但此时子类的实例变量还没完成初始化:你写的private int numTeamLead=2这个赋值操作,是在父类构造器完全执行完毕之后才会执行的。在父类构造器运行阶段,子类的成员变量还处于默认值状态(int类型默认值为0)
  • 等父类构造器执行完成后,子类才会先执行实例变量的初始化(把numTeamLead设为2),接着执行子类构造器里的this.numTeamLead = numTeamLead(这里传入的参数是1,所以numTeamLead被改成1),最后调用employ(),输出1 teamlead

所以首次输出0 teamlead,是因为父类构造器调用重写方法时,子类的numTeamLead还没被初始化到你设置的2,还是默认的0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:41:00