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
相关产品推荐
相关产品推荐

