准备阶段是JVM类加载中真实分配内存并写入零值的物理操作:在方法区为static字段预留固定大小槽位,并用memset等指令将对应内存清零(数值为0、引用为null),普通static字段参与,编译期static final直接赋值,运行期static final先置零后覆写。

准备阶段是 JVM 类加载过程中真实发生内存分配和零值写入的环节,不是概念性动作,而是有明确物理内存操作的步骤。
分配内存:在方法区划出固定槽位
所谓“分配内存”,是指 JVM 解析字节码后,在方法区(HotSpot 中为元空间)中为每个 static 字段 预留一块确定大小的连续空间:
- int、float 占 4 字节,long、double 占 8 字节,char 占 2 字节,boolean 和 byte 各占 1 字节
- 引用类型(如 static String s)占一个机器字长(64 位 JVM 下为 8 字节)
- 这些槽位按字段声明顺序组织,与类的元数据(如常量池地址、字段表指针)一起构成该类在方法区的完整镜像
赋初值:真实清零,不是逻辑约定
“设置默认值”是底层内存操作,JVM 调用类似 memset() 的指令,把对应槽位所有字节设为 0x00:
- 数值型字段 → 全 0 字节,表现为 0、0.0f、'\u0000'、false
- 引用类型字段 → 全 0 字节,即 0x0000000000000000,在 JVM 中就是 null 的二进制表示
- 这一步发生在任何 Java 字节码执行之前,确保不会读到内存残留的随机值
哪些变量参与,哪些不参与
准备阶段只处理特定静态字段,规则很清晰:
- 普通 static 字段(如 static int x;)→ 分配内存并设为 0
- static final 基本类型或字符串字面量(如 static final int MAX = 100;)→ 直接写入编译期确定的值,跳过零值
- static final 运行期值(如 static final long T = System.nanoTime();)→ 先设为 0L,初始化阶段再覆写
- 实例变量(非 static)、局部变量、方法参数 → 完全不在此阶段处理
和初始化阶段的本质区别
准备阶段与初始化阶段是两个独立、不可合并的步骤:
- 准备阶段不执行任何 Java 代码:static {} 块不运行,static int x = 5; 中的 = 5 被完全忽略
- 初始化阶段才执行
方法,按源码顺序执行显式赋值和静态块 - 正因为准备阶段已真实写入零值,初始化阶段才能安全地基于当前值做计算(如 static int a = b + 1; static int b = 5; 中 a 初始为 0,所以得 1)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











