子类覆盖父类更新的值后输出null?求Java变量初始化顺序及原因
问题分析:为什么代码输出null?
核心原因
问题出在父类构造器调用子类重写方法的时机,结合Java对象初始化顺序,导致子类实例变量被两次赋值,最终被重置为null:
- 父类构造器执行时调用了子类的
init方法,此时data被赋值为10; - 但父类构造器执行完成后,子类的实例变量初始化代码
Integer data = null;会再次执行,把data重新设为null。
Java对象初始化顺序详解
创建子类实例时,完整的初始化流程是这样的:
- 执行父类的构造器(子类构造器第一行必须调用父类构造器,这里显式调用了
super(f)); - 父类构造器中调用
init方法,由于该方法被子类重写,实际执行子类的init实现,此时给data赋值为10; - 父类构造器执行完毕后,开始执行子类的实例变量初始化代码(也就是
Integer data = null;这一行),这一步会覆盖之前init方法中给data赋的值; - 最后执行子类构造器中剩余的代码(本例中没有额外代码)。
简单来说,子类实例变量的初始化是在父类构造器执行完成之后才进行的,这就导致父类构造器里调用子类方法给变量赋的值,会被后续的变量初始化代码覆盖。
修复建议
如果想让data保留init方法赋的值,只需要去掉子类中data的显式初始化赋值(因为引用类型默认初始值就是null),改成:
Integer data;
这样就不会在父类构造器执行后重置data的值,最终输出就是10了。
内容的提问来源于stack exchange,提问作者anupamD
相关产品推荐
相关产品推荐

