java深拷贝需切断所有引用链,主要方式有:①序列化(通用但性能低)、②重写clone()(需各层支持cloneable)、③mapstruct(编译期生成映射代码)、④json序列化反序列化(免改源码但有类型与循环引用限制)。

Java中实现对象属性的深层拷贝,关键在于确保原对象及其所有嵌套引用对象都被独立复制,避免修改副本时影响原始数据。这不是简单赋值或浅层复制能解决的问题,必须切断所有共享引用链。
序列化方式:最通用的深拷贝方案
只要对象及其所有成员类都实现了Serializable接口,就能通过字节流完成完整隔离的拷贝。它不依赖字段名、不关心访问修饰符,天然支持任意嵌套结构。
- 优点:逻辑清晰、一次调用即可递归复制全部层级,无需手动处理每个引用字段
- 缺点:性能开销较大(涉及IO和反射),不可序列化的类(如含Thread、Socket等)会失败
- 使用时需注意:捕获
IOException和ClassNotFoundException,建议封装为工具方法复用
重写clone()并手动深拷贝引用字段
在实现Cloneable接口的基础上,重写clone()方法,并对每个引用类型字段调用其自身的clone()或构造新实例。
- 适用于嵌套层级较浅、引用对象可控的场景(如Address、OrderItem等POJO)
- 必须确保被引用的类也支持克隆(同样实现Cloneable并重写方法),否则容易漏掉某一层
- 示例中常见错误是只调用
super.clone()而未处理address = (Address) this.address.clone(),这仍是浅拷贝
使用MapStruct生成类型安全映射
MapStruct不是运行时反射工具,而是在编译期生成普通Java代码,因此性能接近手写,且支持自定义转换逻辑与嵌套映射。
- 适合DTO/VO之间大量字段映射的项目,尤其配合Lombok可大幅减少样板代码
- 需声明Mapper接口并标注
@Mapper,编译后自动产生实现类,无需额外配置运行时依赖 - 对集合、日期、枚举等特殊类型提供内置转换器,也可编写自定义
@Named方法处理复杂逻辑
JSON序列化反序列化(Gson/Jackson)
将对象转为JSON字符串再解析成新对象,本质是“序列化→文本→反序列化”,间接达成深拷贝效果。
- 优势是无需修改原有类(不要求实现Serializable或Cloneable),适合第三方类或遗留系统
- 局限性明显:不支持含函数、静态字段、transient字段或循环引用的对象;丢失泛型类型信息(需TypeToken辅助)
- 建议仅用于简单数据载体(如DTO、配置类),避免在高频调用路径中使用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











