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

