静态成员初始化严格发生在类加载的“初始化”阶段,按源码声明顺序执行且仅触发一次;父类优先于子类初始化,六种主动使用场景(如new、调用静态方法等)才会触发该过程。

Java类加载过程中,静态成员的初始化不是随意发生的,而是严格遵循JVM规范的阶段性、有序性流程。核心在于:**静态代码块和静态变量按源码声明顺序执行,且只在类首次主动使用时触发一次**。
类加载五阶段与静态初始化发生点
静态成员初始化发生在“初始化”阶段,这是类加载流程的第五步,前四步不执行任何用户代码:
- 加载:读取.class字节码,生成Class对象(无代码执行)
- 验证:检查字节码合法性(无代码执行)
- 准备:为static变量分配内存并设默认值(如int=0、Object=null;此时不执行赋值语句)
- 解析:将符号引用转为直接引用(无代码执行)
- 初始化:真正执行static变量显式赋值、static代码块——这才是你看到的“打印日志”发生的时刻
单个类内静态成员执行顺序
在同一类中,所有静态成分(变量声明、静态代码块、静态方法调用)按源码自上而下顺序执行,不分“变量优先”或“代码块优先”:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 先遇到的static{}就先执行
- 先声明的static变量,其初始化表达式(如
static String s = init();)也在此时求值 - 若变量初始化调用了静态方法,该方法体内的代码会立即执行,再返回结果赋值
- 示例顺序:
static { println("A"); }→static int x = 1;→static { println("B"); }→static String y = getValue();
继承体系下的静态初始化顺序
当存在父子类关系时,静态初始化严格遵守“父类优先”原则,且每层内部仍保持自上而下顺序:
- 先完整完成父类的初始化(静态变量 + 静态块)
- 再执行子类的初始化(静态变量 + 静态块)
- 子类初始化不触发父类重复初始化(已执行过,JVM保证只一次)
- 注意:静态初始化与构造器无关,哪怕你只调用子类静态方法,父类静态部分也会先跑一遍
触发静态初始化的六种主动使用场景
只有满足以下任一条件,JVM才会启动类的初始化阶段(从而执行静态成员):
- new 创建该类实例
- 访问/修改该类的非final静态字段
- 调用该类的静态方法
- 反射调用(如
Class.forName("X")) - 初始化子类时,其直接父类尚未初始化 → 父类被强制初始化
- 运行包含main()方法的类(即程序入口类)
特别提醒:static final常量(编译期常量)访问不会触发初始化,因其值在编译时已内联到调用处。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










