news 2026/6/23 19:07:47

Java 中 new 一个对象的过程是怎么样的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 中 new 一个对象的过程是怎么样的?

Java 中new 一个对象的过程是从字节码解析到内存分配、初始化、引用返回的完整链路,涉及 JVM 类加载、内存管理、构造方法执行等核心机制。以下按「JVM 层面的核心步骤」+「代码层面的直观拆解」展开,兼顾底层原理和实际理解:

一、核心前提:类必须先加载(首次创建对象时)

如果该类从未被 JVM 加载过,执行new前会先触发类加载流程(加载→验证→准备→解析→初始化),确保类的元数据(如字段、方法、常量池)被加载到方法区(JDK 1.8+ 为元空间)。

  • 加载:通过类的全限定名读取字节码文件(.class);
  • 初始化:执行静态代码块(<clinit>)、静态变量赋值(如static int a = 10);
  • 注意:类加载仅执行一次,后续创建该类对象时跳过此步骤。

二、new 对象的核心步骤(JVM 层面)

User user = new User("张三", 20);为例,完整流程如下:

步骤1:检查类加载状态 + 分配内存

JVM 先确认User类已加载,然后为新对象分配堆内存

  • 内存大小确定:根据类的元数据(字段类型、数量)计算对象所需内存(如对象头 + 实例字段 + 对齐填充);
  • 内存分配方式
    • 「指针碰撞」:堆内存规整(Serial/ParNew 收集器),JVM 移动空闲指针,划分出对象所需内存;
    • 「空闲列表」:堆内存碎片化(CMS 收集器),JVM 从空闲列表中找到足够大的内存块分配;
  • 线程安全保障
    • 方案1:CAS + 失败重试(保证分配原子性);
    • 方案2:TLAB(本地线程分配缓冲)—— 每个线程在堆中预留一小块内存,优先在 TLAB 分配,避免竞争(默认开启)。
步骤2:内存初始化(零值填充)

分配完内存后,JVM 会将对象的实例字段初始化为对应类型的零值(不执行赋值语句,仅清空内存):

  • 例如:Username字段(String 类型)被设为nullage字段(int 类型)被设为0,引用类型默认null,基本类型默认对应零值(boolean→false,long→0L 等);
  • 目的:保证对象字段在构造方法执行前,不会出现“未初始化的脏数据”。
步骤3:设置对象头(Object Header)

在分配的内存中设置对象头信息,包含:

  • Mark Word:存储对象的哈希值、GC 分代年龄、锁状态、偏向锁线程 ID 等;
  • 类型指针:指向对象所属类的元数据(如User.class),JVM 通过该指针确认对象的类型;
  • (数组对象额外)数组长度:若为数组对象,还会存储数组长度字段。
步骤4:执行实例初始化方法(<init>

这是「代码层面感知最明显」的步骤,JVM 调用对象的构造方法(<init>是编译器生成的初始化方法,对应代码中的构造函数):

  • 执行顺序:
    1. 先调用父类的<init>方法(隐式super(),若未显式调用,编译器自动添加),递归直到Object类;
    2. 执行实例变量的显式赋值(如private String name = "默认名");
    3. 执行构造方法中的自定义逻辑(如this.name = name; this.age = age;);
  • 关键:<init>方法是对象初始化的核心,只有执行完<init>,对象才是“完整可用”的
步骤5:返回对象引用

JVM 将堆中对象的内存地址赋值给栈中的引用变量(如user):

  • 注意:引用变量(user)存储在栈帧的局部变量表中,指向堆中的实际对象;
  • 特殊情况:JIT 优化可能将对象“标量替换”到栈上(逃逸分析),避免堆内存分配(如局部对象未逃逸出方法)。

三、代码层面的直观拆解(结合示例)

以自定义User类为例,直观对应上述步骤:

classUser{// 实例字段privateStringname;privateintage;// 静态代码块(类加载时执行,仅一次)static{System.out.println("User类初始化(静态代码块)");}// 构造方法publicUser(Stringname,intage){this.name=name;this.age=age;System.out.println("构造方法执行:初始化name和age");}}// 创建对象publicclassTest{publicstaticvoidmain(String[]args){Useruser=newUser("张三",20);}}
执行输出(首次创建):
User类初始化(静态代码块) 构造方法执行:初始化name和age
对应步骤:
  1. 首次执行new User()→ 触发User类加载,执行静态代码块;
  2. JVM 为User对象分配堆内存;
  3. 内存零值填充:name=nullage=0
  4. 设置对象头(Mark Word + 指向User.class的类型指针);
  5. 执行<init>方法:
    • 调用Object<init>(隐式);
    • 执行构造方法逻辑,将name设为“张三”,age设为 20;
  6. 将堆中对象地址赋值给栈中的user引用。

四、关键补充:易混淆的细节

1.newvsclonevs 反射创建对象
  • new:触发类加载 + 完整的<init>执行;
  • clone:不执行构造方法,直接拷贝已有对象的内存(浅拷贝);
  • 反射(Class.newInstance()/Constructor.newInstance()):触发<init>,但可绕过访问权限(如私有构造)。
2. 逃逸分析对new的影响

若对象未逃逸出方法(如仅在方法内使用),JIT 会优化为「栈上分配」,无需在堆中创建,减少 GC 压力:

publicstaticvoidtest(){// 对象仅在方法内使用,逃逸分析后栈上分配Useru=newUser("李四",25);}
3. 构造方法的本质

构造方法不是“创建对象”,而是“初始化对象”—— 对象的内存分配在构造方法执行前已完成,构造方法仅负责给字段赋值。

五、总结:new 对象的核心链路

类加载(首次) → 分配堆内存 → 零值填充 → 设置对象头 → 执行<init>(父类构造+实例赋值+自定义逻辑) → 返回对象引用
  • 核心:JVM 先完成“内存层面的对象创建”,再通过构造方法完成“业务层面的初始化”;
  • 关键:只有执行完<init>,对象才是合法可用的,否则可能出现字段未初始化的异常。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 12:14:37

从规则引擎到大模型:文档生成技术的十年进化与现在的最佳实践

文档生成技术并不是近两年才出现的&#xff0c;它经历了一个非常典型的“工程化 → 模板化 → 智能化”演变过程。 今天&#xff0c;随着 AI 的加速渗透&#xff0c;文档处理已经不再是“自动化办公软件”的范畴&#xff0c;而是一个完整的「内容生产技术栈」。 这篇文章&…

作者头像 李华
网站建设 2026/6/23 21:00:49

AI客户端终极指南:多平台支持与工作区管理快速上手

AI客户端终极指南&#xff1a;多平台支持与工作区管理快速上手 【免费下载链接】AIaW AI as Workspace - 精心设计的 AI (LLM) 客户端。 全功能&#xff0c;轻量级&#xff1b;支持多工作区、插件系统、跨平台、本地优先实时云同步、Artifacts 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/6/23 19:15:47

安全审查--跨站请求伪造--Fetch Metadata防护模式

安全Top10 https://cheatsheetseries.owasp.org/IndexTopTen.html---------------------------------------------------------------------------------------摘要&#xff1a;从小白开始逐层讲解Fetch Metadata一、从一个现代浏览器的困惑说起1.1 新时代的安全挑战想象一下这…

作者头像 李华
网站建设 2026/6/23 19:13:13

uni-app x封装request,统一API接口请求

config.baseURL https://api.example.com // api地址config.timeout 8000 // 单位毫秒&#xff0c;对应8秒config.loadingText 加载中...config.loading true // 开启 loading 动画return config})/* 2. 请求拦截 */http.interceptors.request.use((config) > {const to…

作者头像 李华
网站建设 2026/6/23 19:10:19

4大维度解析DeepLX与官方API:技术实战与成本效益终极评测

4大维度解析DeepLX与官方API&#xff1a;技术实战与成本效益终极评测 【免费下载链接】DeepLX DeepL Free API (No TOKEN required) 项目地址: https://gitcode.com/gh_mirrors/de/DeepLX 在机器翻译领域&#xff0c;DeepL以其卓越的翻译质量广受好评&#xff0c;但其官…

作者头像 李华
网站建设 2026/6/23 21:00:51

本地 AI 服务难共享?TRAE SOLO+cpolar 轻松打破局域网枷锁

引言&#xff1a;AI时代&#xff0c;你还在为“内网”所困吗&#xff1f; TRAE SOLO 是一款集成 AI 能力的开发工具&#xff0c;能理解开发需求、拆解任务并调用工具完成编码、调试等工作&#xff0c;适合 AI 开发者、程序员等群体。其 SOLO 模式可自主推进开发流程&#xff0…

作者头像 李华