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

Java子类访问父类变量返回null:显式调用父类构造仍取值为null

问题根因

当前实现方式不可行,核心是Java类初始化、实例构造的执行时序完全错配,和要不要使用Getter/Setter没有任何关系。

实际执行流程拆解

你代码的运行顺序和你的预期完全相反,具体节点如下:

  • JVM启动时定位到Child类的main方法入口,首先触发Child类的加载与初始化流程
  • Child类初始化阶段会按定义顺序执行所有静态字段的赋值操作,此时执行static final String parentName = Parent.name;:
    • 这一步执行时,Parent类还未被触发初始化,也没有任何Parent类的实例被创建,Parent.name作为引用类型字段,JVM会给默认初始值null,这个null值会被永久固定为parentName的初始取值
  • 等Child类初始化完成,才进入main方法的实际执行逻辑:
    • 执行new Child()时,才会向上追溯触发父类Parent的构造方法调用,打印"Parent constructor is called",把Parent.name的值赋值为"Adam"
  • 最后执行打印操作时,parentName早在类初始化阶段就已经绑定了null值,不会随着Parent.name的后续修改发生变化,最终输出null

常见认知澄清

  • 不需要强制依赖Getter/Setter才能读取父类变量。只要保证读取动作的发生时机在父类构造完成之后,不管是直接访问public修饰的父类变量,还是调用Getter方法,都能正常拿到赋值后的值
  • 额外注意:static final修饰的字段,如果取值不是编译期可确定的常量(比如这里的Parent.name是运行时才能拿到的值),只会在类初始化阶段执行一次赋值,后续不会重新计算取值,这也是parentName始终保持null的直接原因

调整方向

  • 不要在子类的静态初始化阶段,直接读取需要靠父类构造才能完成赋值的变量。把读取动作移到实际使用的场景下:比如在main方法内直接打印Parent.name,或者把parentName从静态字段改成实例字段,在父类构造执行完成后再触发赋值
  • 如果本意是要读取父类的实例成员变量(而非当前代码里的静态类变量),只要父类构造正常执行,子类在实例方法、实例字段上下文里直接访问即可,不需要额外编写Getter/Setter

内容的提问来源于stack exchange,提问作者Steven.Q

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 02:54:01