java深拷贝需确保新对象与原对象完全独立,常用方式有:序列化(要求serializable接口,忽略static/transient字段)、手动重写clone()(性能好但侵入性强)、第三方库(如serializationutils)。

Java 中实现对象的深拷贝,核心是**让新对象与原对象完全独立,修改副本不会影响原对象,包括其所有嵌套引用类型字段**。没有通用“一键深拷贝”方法,需根据场景选择合适方式。
使用序列化(最常用、通用性强)
原理:将对象写入字节流再读出,天然绕过引用共享。要求类及其所有字段类型都实现 Serializable 接口,且无不可序列化的资源(如 Socket、Thread)。
示例代码:
public static <t extends serializable> T deepCopy(T obj) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
@SuppressWarnings("unchecked")
T copy = (T) ois.readObject();
ois.close();
return copy;
}</t>
- 优点:不依赖类内部结构,支持任意嵌套层级
- 注意:静态字段、transient 字段不会被复制;性能略低,不适合高频调用
- 建议:对 DTO、VO 等纯数据类优先考虑此法
手动重写 clone() 方法(可控性强、性能好)
需类实现 Cloneable 接口,并在 clone() 中对每个引用类型字段调用其自身的 clone() 或新建实例赋值。
示例:
public class Person implements Cloneable {
private String name;
private Address address; // 假设 Address 也实现了深 clone
@Override
protected Person clone() {
try {
Person cloned = (Person) super.clone();
// 对引用类型字段单独深拷贝
cloned.address = this.address != null ? this.address.clone() : null;
return cloned;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
- 优点:零序列化开销,逻辑清晰,可精确控制哪些字段需要深拷贝
- 缺点:侵入性强,每个引用字段对应的类都需支持克隆;易遗漏字段,维护成本高
- 适用:结构稳定、对性能敏感的内部模型类
使用第三方库(开发效率高)
如 Apache Commons Lang 的 SerializationUtils.clone()(本质仍是序列化),或更灵活的 MapStruct、Dozer(基于映射规则)、DeepClone 库等。
Maven 引入 Commons Lang:
<dependency><groupid>org.apache.commons</groupid><artifactid>commons-lang3</artifactid><version>3.12.0</version></dependency>
使用:
Person copy = SerializationUtils.clone(originalPerson);
- 推荐用于快速验证或非核心模块
- 注意:部分库(如 Dozer)已停止维护,选型时确认活跃度和兼容性
避免踩坑的关键细节
-
不要只调用
super.clone():它只做浅拷贝,引用字段仍指向同一对象 - 检查 final 字段:final 引用类型无法在 clone 中重新赋值,需在构造时处理或改用其他方式
- 慎用 JSON 转换模拟深拷贝(如 Gson.toJson().fromJson()):会丢失类型信息、 transient 字段、自定义序列化逻辑,且性能差
- 循环引用要小心:序列化方式默认支持;手动 clone 需额外状态记录防止栈溢出
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











