静态变量初始化发生在类加载的“初始化”阶段,由jvm在类首次主动使用时执行一次方法,按源码顺序合并静态赋值与静态块,父类先于子类、从上到下执行。

静态变量初始化发生在类加载的“初始化”阶段,不是声明时立即执行,也不是加载字节码时就赋值,而是由 JVM 在类首次被主动使用时,统一、有序、仅执行一次。
初始化实际在 方法里完成
Java 编译器会把同一类中所有静态变量显式赋值语句(如 static int x = 5;)和静态代码块(static { ... })按源码书写顺序合并进一个特殊方法:
- 由 JVM 自动调用,不能被手动调用或重载
- 只在类初始化阶段执行一次
- 可通过 javap -c ClassName 查看其字节码指令,全是按序排列的 putstatic 和逻辑操作
-
public static final 基本类型或字符串常量(如 PORT = 8080)不进入
,编译期直接内联,访问也不触发类初始化
初始化分三阶段,静态变量命运各不同
类加载不是一步到位,静态变量在不同阶段有明确状态:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 加载阶段:仅读入 .class 字节码,生成 Class 对象;静态变量尚未分配内存
- 准备阶段:为所有 static 变量分配内存,并设默认值(int→0,Object→null);此时不执行任何赋值语句或静态块
-
初始化阶段:执行
——这才是你写的 static int y = getValue(); 和 static { init(); } 真正运行的时刻
执行顺序严格受控:先父后子、从上到下
静态部分不是乱序运行,而是一条清晰链条:
- 父类静态变量赋值 → 父类静态代码块(按父类源码顺序穿插)
- 子类静态变量赋值 → 子类静态代码块(按子类源码顺序穿插)
- 同一类中,谁写在前面,谁先执行;静态块中不能引用后声明的静态变量(编译报错)
- 若某静态变量依赖另一个(如 static int b = a + 1;),则 a 必须已在此前完成显式初始化
什么操作真正触发初始化?不是所有访问都算
只有以下“主动使用”行为才会走到初始化阶段,启动
- new 某个类的实例
- 调用该类的静态方法
- 读写该类的非final静态字段(注意:final static 常量不算)
- 反射调用 Class.forName("X")(Class.forName("X", false, cl) 中第二个参数为 false 则跳过)
- 初始化子类时,强制先初始化其父类
- JVM 启动时直接运行含 main() 的类
反例:仅写 Class c = X.class;、声明数组 X[] arr = new X[5];、访问 Math.PI,均不触发初始化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










