浅拷贝仅复制对象头和基本字段,引用字段共享堆内存;深拷贝则递归新建所有引用对象,彻底解耦。二者性能与风险差异源于内存分配策略:浅拷贝快但存在可变引用安全隐患,深拷贝慢但完全隔离。

浅拷贝只复制对象头和基本字段,引用字段仍共享堆内存
Java中浅拷贝本质是调用Object.clone()的默认行为:它在堆上分配一块**与原对象大小相同的新内存空间**,然后把原对象的字节码(包括对象头、实例字段值)逐字节复制过去。对int、boolean、double等基本类型,值被真实复制;但对String、List、自定义对象等引用类型,复制的只是栈中存储的**引用地址值**(例如0x7f8a12),而非地址指向的那个对象本身。结果就是两个对象的引用字段指向同一块堆内存区域——改其中一个的address.city,另一个立刻可见变化。
深拷贝必须递归重建所有引用层级的对象图
深拷贝的目标是让新旧对象彻底解耦,这要求对每个引用类型字段都执行“新建+复制”两步操作:
- 遇到
Address address字段,不能只复制0x7f8a12这个地址,而要new Address()创建全新实例,并把原address.city、address.street的值赋给它 - 如果
Address内部还有引用字段(比如GeoLocation geo),就得继续向下递归,直到所有嵌套对象都被实例化并填充 - 最终形成一棵独立的对象树,根节点和所有子节点都位于不同内存地址,彼此无共享
实现方式直接反映底层动作差异
浅拷贝通常只需implements Cloneable并调用super.clone()——JVM直接执行内存块拷贝指令(类似C语言的memcpy)。深拷贝没有统一语法糖,必须手动控制每层对象生命周期:
-
重写clone()做递归克隆:在
User.clone()里调用address.clone(),前提是Address也实现了Cloneable - 序列化反序列化:把对象转成字节数组再还原,JVM自动遍历整个对象图并重建所有对象——本质是绕过引用复用,强制走构造流程
- 构造器注入或BeanUtils.copyProperties:显式调用新对象构造器,逐字段赋值,对引用字段主动new子对象
性能与风险的根本来源是内存分配策略
浅拷贝快,因为只涉及一次内存分配(新对象本身)和一次内存拷贝(字段值平移);深拷贝慢且耗内存,因为它触发多次new操作,可能创建数十个中间对象。更关键的是:若某层引用对象不可变(如String、LocalDateTime),浅拷贝实际安全;但一旦存在可变引用(如ArrayList、HashMap或自定义POJO),浅拷贝就埋下并发修改或意外覆盖的隐患——这不是代码写错,而是内存布局决定的必然行为。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南








