Java:静态变量默认初始化是否先于静态初始化执行?
静态变量默认初始化与静态初始化的执行顺序
嘿,这个问题问到点子上了!咱们结合你给出的代码,一步步理清Java类加载时静态变量初始化的细节:
核心结论
静态变量的**默认初始化(分配内存+设置默认值)是在静态初始化(执行静态代码块、静态变量显式赋值)**之前完成的,分属类加载的两个不同阶段:
- 准备阶段:完成静态变量的内存分配与默认值赋值;
- 初始化阶段:按代码顺序执行静态代码块和静态变量的显式赋值语句。
结合代码的详细执行流程
先看你的测试代码:
class Test { static { System.out.println(Test.a); // prints 0 a = 99; // a get 99 System.out.println(Test.a); // prints 99 } static int a = 10; static { System.out.println(a); // prints 10 } public static void main(String[] args) { } }
咱们跟着JVM的类加载步骤走:
- 准备阶段:JVM先为静态变量
a分配内存空间,并将其设置为int类型的默认值0——这一步早于所有静态代码块的执行。 - 初始化阶段:JVM按代码中静态元素的出现顺序,依次执行初始化逻辑:
- 执行第一个静态代码块:
- 打印
Test.a:此时a还没被显式赋值,所以输出准备阶段的默认值0; - 手动将
a赋值为99,此时a的内存值更新为99; - 再次打印
a,输出99。
- 打印
- 执行静态变量
a的显式赋值语句static int a = 10;:这一步会把a的当前值(99)覆盖为10。 - 执行第二个静态代码块:打印
a,此时a已经被显式赋值为10,所以输出10。
- 执行第一个静态代码块:
再敲个重点
静态代码块里可以访问静态变量,是因为在准备阶段已经完成了默认初始化;而静态变量的显式赋值会覆盖之前的默认值(甚至是静态代码块里手动设置的值),这完全取决于代码的书写顺序。
内容的提问来源于stack exchange,提问作者Number945
相关产品推荐
相关产品推荐

