Java中new对象包含五个严格顺序步骤:1.类加载检查;2.分配内存;3.初始化零值;4.设置对象头;5.执行构造器逻辑。每步缺一不可,共同确保对象安全正确创建。

Java 中 new 一个对象,不只是“分配内存”这么简单——它是一整套有严格顺序的初始化流程,每一步都影响对象能否正确、安全地使用。
1. 类加载检查(Class Loading Check)
执行 new 时,JVM 先确认这个类是否已被加载、解析和初始化。如果还没加载,会触发类加载机制:加载 → 验证 → 准备 → 解析 → 初始化。比如第一次 new ArrayList(),JVM 就会确保 java.util.ArrayList 这个类已准备好,包括它的静态字段、静态代码块都执行完毕。
- 没加载?走双亲委派模型去加载 class 文件
- 加载失败(如 NoClassDefFoundError)?new 直接抛异常,根本到不了后续步骤
2. 分配内存(Memory Allocation)
在堆中划出一块足够存放该对象实例数据的连续内存空间。大小由类的字段(含父类)决定,与方法无关。JVM 用两种常见策略:
- 指针碰撞(Bump the Pointer):适用于内存规整(如 Serial、ParNew),移动空闲指针即可
- 空闲列表(Free List):适用于内存碎片化(如 CMS),需从记录表中找合适空闲块
如果是多线程并发 new,JVM 还会通过 TLAB(Thread Local Allocation Buffer) 避免同步开销——每个线程先在自己小块里分配,不够再加锁申请。
立即学习“Java免费学习笔记(深入)”;
3. 初始化零值(Zero Initialization)
分配完内存后,JVM 立即把这块内存所有字节设为零(不包括对象头)。这保证了即使你没显式赋值,字段也有默认值:
- int → 0,boolean → false,引用类型 → null
- 注意:这步不执行任何 Java 代码,不是调构造器,只是“清零”
4. 设置对象头(Object Header Setup)
在对象起始位置写入对象头信息,包含两部分:
- Mark Word:存储哈希码、GC 分代年龄、锁状态(偏向锁标记等)
- Class Metadata Address:指向方法区中该类的 Class 对象地址(用于类型识别、反射、多态)
5. 执行 init 方法(即构造器逻辑)
最后才真正执行你的 Java 代码:按声明顺序初始化成员变量 → 执行实例初始化块 → 调用构造方法(含 super() 链)。这才是我们常说的“对象创建完成”的时刻。
- 如果构造器抛异常,对象创建失败,但内存可能已分配(之后被 GC 回收)
- 此时 this 引用已存在,但对象处于“半初始化”状态——慎在构造器中泄露 this(如启动线程、注册监听器)
基本上就这些。理解 new 的完整过程,能帮你避开空指针、线程安全、类加载失败等典型问题,不是炫技,是写健壮代码的基础。










