java中实现深度复制需主动干预:重写clone()并手动深拷贝可变引用字段,或用序列化(要求serializable)、拷贝构造器等方式;注意arraylist.clone()是浅拷贝、不可变对象无需处理、循环引用和第三方类限制等问题。

Java 中 clone() 方法默认只做浅拷贝,对引用类型属性仅复制地址,不创建新对象。要实现深度复制,必须主动干预,逐层切断共享引用。
重写 clone() 并手动深拷贝每个可变引用字段
这是最直接可控的方式,前提是所有被引用的类也支持克隆(即实现 Cloneable 并重写 clone()):
- 在目标类中重写
public Object clone(),调用super.clone()获取基础副本 - 对每个可变引用字段(如自定义对象、
ArrayList、HashMap等),单独调用其clone()方法或新建实例 - 对集合类不能只调用
list.clone()(它仍是浅的),而要遍历元素并克隆每个可变元素 - 不可变对象(
String、Integer、LocalDateTime等)无需处理,直接赋值即可
用序列化方式实现通用深拷贝
适用于所有可序列化的类,无需修改原有类结构,但要求整个对象图中所有类都实现 Serializable:
- 将对象写入字节流再反序列化,天然生成全新对象树
- 可封装为工具方法,一行代码完成深拷贝:
SerializationUtils.clone(obj)(Apache Commons Lang) - 注意:含
transient字段、非序列化资源(如文件句柄、线程)或 Lambda 表达式时会失效
用构造器或静态工厂方法替代 clone()
更清晰、更易维护,尤其适合 POJO 或 DTO 类:
- 为类添加拷贝构造器,如
public Person(Person other) - 在构造器内部对引用字段做深初始化,例如
this.address = new Address(other.address) - 集合字段可用
new ArrayList(other.list)—— 对String等不可变元素有效;若含可变对象,仍需逐个 new 或 clone
避免踩坑的关键细节
深拷贝不是“调一次 clone 就完事”,常见疏漏包括:
-
ArrayList.clone()只复制数组容器,内部元素仍是原引用 —— 必须遍历并克隆每个元素 - 嵌套层级较深时,容易漏掉某一层引用,导致部分共享、部分独立,引发隐蔽 bug
- 循环引用对象(A 引用 B,B 又引用 A)用序列化可能抛出异常,需额外处理
- 第三方类未实现
Cloneable或Serializable时,只能手动 new + 属性赋值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











