外部类与内部类静态初始化块执行顺序为何受main方法位置影响?
为什么main方法位置会影响输出顺序?
这个差异的核心原因是Java类的按需加载机制,以及不同场景下类加载的触发时机不同,再加上Java 16+对非静态内部类静态初始化块的支持,共同导致了输出顺序的变化。
先明确两个关键规则
- Java类不是一次性全部加载,而是用到才加载(按需加载),类的静态初始化块会在类加载完成后立刻执行。
- 从Java 16开始,非静态内部类也允许定义静态初始化块(之前版本会编译报错)。
分场景拆解输出逻辑
场景1:运行Foo类的main方法
- JVM启动后,首先要加载
Foo类(因为要执行它的main方法),加载时直接触发Foo的静态初始化块,输出Foo。 - 执行
new Foo().new Bar()时,需要创建Bar的实例,此时JVM才会加载Bar类,触发其静态初始化块输出Bar。 - 最终输出顺序:
FooBar。
场景2:运行Main类的main方法
- JVM启动后先加载
Main类,执行它的main方法。 - 执行
new Foo().new Bar()时,JVM需要先解析Bar这个内部类的类型定义,此时会优先触发Bar类的加载,执行其静态初始化块输出Bar;随后创建Foo实例时,才会加载Foo类并触发其静态初始化块输出Foo。 - 最终输出顺序:
BarFoo。
简单来说,两种场景下类的加载触发时机不同:前者先因为执行main加载Foo,后者先因为解析内部类定义加载Bar,从而导致静态初始化块的执行顺序反转。
内容的提问来源于stack exchange,提问作者Sy Pham
相关产品推荐
相关产品推荐

