准备阶段为static变量在方法区分配内存并设默认值,不执行任何java代码;数值类型为0、引用类型为null,显式赋值(如x=5)留待初始化阶段的执行。

准备阶段不执行任何 Java 代码,只做两件事:为类的静态变量(static 变量)在方法区分配内存,并设置其默认初始值。
分配内存:发生在方法区,与对象堆内存无关
静态变量属于类,不是实例,因此 JVM 在准备阶段就在方法区(JDK 8+ 是元空间)为其分配固定内存空间。这个动作和 new 多少个对象无关,只和类是否被加载有关。
例如:
- public static int count; → 分配 4 字节,初始值为 0
- public static Boolean flag; → 分配引用空间,初始值为 null
- public static final String NAME = "abc"; → 因是编译期常量,直接放入常量池,准备阶段就设为 "abc"(特例)
赋初值:仅限默认值,不是代码里写的值
这里的“初值”严格指 JVM 规定的类型默认值,不是你在源码中写的显式值:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 数值类型(byte/short/int/long/float/double)→ 0 或 0.0
- char → '\u0000'
- boolean → false
- 引用类型(Object、String、自定义类等)→ null
比如 public static int x = 5; 中的 5 不在此阶段赋值——它要等到初始化阶段,由 <clinit></clinit> 方法执行时才真正写入。
注意区分:准备阶段 ≠ 初始化阶段
很多人混淆“分配内存并设默认值”和“执行赋值语句”,关键区别在于:
- 准备阶段:无逻辑、无顺序、无依赖,纯 JVM 内存操作,不运行任何 static 赋值或 static{} 块
- 初始化阶段:执行
<clinit></clinit>,按源码顺序跑 static 变量显式赋值 + static{},此时才会把 x = 5 这样的值真正写进去
所以,如果你在 static{} 里打印 x,看到的是 5;但如果在准备阶段“中途查看”(如通过 JVMTI 工具),它只能是 0——因为赋值动作尚未发生。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










