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

准备阶段不执行任何 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项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 数值类型(byte/short/int/long/float/double)→ 0 或 0.0
- char → '\u0000'
- boolean → false
- 引用类型(Object、String、自定义类等)→ null
比如 public static int x = 5; 中的 5 不在此阶段赋值——它要等到初始化阶段,由 <clinit> 方法执行时才真正写入。
注意区分:准备阶段 ≠ 初始化阶段
很多人混淆“分配内存并设默认值”和“执行赋值语句”,关键区别在于:
- 准备阶段:无逻辑、无顺序、无依赖,纯 JVM 内存操作,不运行任何 static 赋值或 static{} 块
- 初始化阶段:执行
<clinit>,按源码顺序跑 static 变量显式赋值 + static{},此时才会把 x = 5 这样的值真正写进去
所以,如果你在 static{} 里打印 x,看到的是 5;但如果在准备阶段“中途查看”(如通过 JVMTI 工具),它只能是 0——因为赋值动作尚未发生。

















