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

Java访问子类静态字段时父类初始化的规范疑问

Java静态字段引用与父类初始化的疑问解答

你引用的《Java 21规范》内容:

引用静态字段仅会初始化实际声明该字段的类或接口,即使通过子类、子接口或实现接口的类引用。
类或接口不会在其他任何情况下被初始化。

但你忽略了规范中类初始化的前置核心规则:在初始化一个类时,必须先初始化它的直接父类(如果父类尚未完成初始化)。

来看你的测试代码:

public class Base {
    static {
        System.out.println("Base");
    }
}
public class Derived extends Base  {
    static {
        System.out.println("Derived");
    }
    public static int foo = 2;
}
public class Main {
    public static void main(String[] args) {
        System.out.println(Derived.foo);
    }
}

程序运行输出:

Base
Derived
2

原因分析

当Main中引用Derived.foo时,由于foo是Derived类直接声明的静态字段,JVM会触发Derived类的初始化流程。而根据规范要求,子类初始化的前提是父类必须先完成初始化——此时Base还未被初始化,所以JVM会先执行Base的静态代码块,完成Base的初始化;之后才会执行Derived的静态代码块、初始化foo字段,最后输出2。

是否违反规范?

完全不违反。你引用的规范条款只是限定“引用静态字段不会因为通过子类引用而直接初始化父类”,但它并没有否定“子类初始化必须先初始化父类”这一基础规则。这里的父类初始化是子类初始化的必要前置步骤,而非由引用静态字段直接触发的父类初始化,和规范描述完全不冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:12:04