浅拷贝仅复制对象本身及一层引用,引用字段共享内存;深拷贝递归复制整个对象图,完全隔离。Java中clone()默认为浅拷贝,深拷贝需手动处理引用或借助序列化、第三方库。

浅拷贝只复制对象本身,不复制它引用的其他对象;深拷贝则递归复制整个对象图,包括所有被引用的对象。
浅拷贝:只复制一层引用
浅拷贝创建一个新对象,将原对象的字段值(基本类型直接复制值,引用类型只复制地址)逐个复制过去。这意味着两个对象的引用字段指向同一块内存,修改其中一个引用对象的内容,另一个也会受影响。
- Java 中常用
Object.clone()实现(需实现Cloneable接口) - 对于包含 String、Integer 等不可变类的引用字段,行为上“看起来像深拷贝”,因为它们无法被修改
- 若对象含可变引用(如
ArrayList、自定义对象),需手动处理这些字段才能避免共享
深拷贝:完全独立的对象副本
深拷贝确保新对象与原对象在内存中彻底隔离,所有嵌套引用的对象也都被重新创建并复制。修改副本不会影响原对象,反之亦然。
- 常见实现方式:序列化(
ObjectOutputStream+ObjectInputStream),要求所有嵌套类都实现Serializable - 手动重写
clone()方法,在其中对每个引用字段调用其自身的clone()或新建实例并复制内容 - 使用第三方库(如 Apache Commons Lang 的
SerializationUtils.clone()或 Gson/JSON 方式转存再解析)
如何判断该用哪种拷贝
关键看是否需要隔离状态变更。如果对象结构简单、不含可变引用,或业务逻辑允许共享部分数据,浅拷贝足够且高效;若涉及并发修改、缓存复用、回滚场景(如编辑前保存快照),必须用深拷贝。
立即学习“Java免费学习笔记(深入)”;
- 集合类(如
List)做浅拷贝后,list1.get(0).setName("A")会影响list2.get(0) - DTO 转换、API 响应封装等常隐式需要深拷贝,否则可能意外暴露内部状态
- 注意性能开销:深拷贝耗时更长、内存占用更高,尤其对象图复杂或含大数组时
一个典型易错点
很多人以为实现了 Cloneable 并重写了 clone() 就是深拷贝,其实默认仍是浅拷贝——除非你显式对每个引用字段做了复制操作。
- 错误写法:
return new Person(this.name, this.address);—— 若address是对象引用,仍共享 - 正确做法:
return new Person(this.name, new Address(this.address));或调用this.address.clone() - 建议为可拷贝类提供明确命名的方法,如
deepCopy(),避免语义混淆










