深克隆java对象的方式
Java 对象深克隆(Deep Clone)的几种实现方式
深克隆是指创建一个新对象,并递归复制原对象及其引用的所有对象,使得新对象与原对象完全独立,修改其中一个不会影响另一个。以下是Java中实现深克隆的几种主要方式:
1. 序列化/反序列化方式
这是最通用的深克隆方法,适用于任何实现了Serializable
接口的对象。
import java.io.*;public class DeepCloneUtil {@SuppressWarnings("unchecked")public static <T extends Serializable> T clone(T obj) {try (ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos)) {oos.writeObject(obj);try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais)) {return (T) ois.readObject();}} catch (IOException | ClassNotFoundException e) {throw new RuntimeException("Deep clone failed", e);}}
}// 使用示例
Person original = new Person("张三", 25);
Person cloned = DeepCloneUtil.clone(original);
优点:
- 通用性强,适用于任何可序列化对象
- 实现简单
缺点:
- 性能较低(涉及I/O操作)
- 要求所有引用的对象都必须实现
Serializable
接口 - 无法克隆
transient
字段
2. 手动实现Cloneable接口
通过重写clone()
方法实现深克隆。
class Address implements Cloneable {private String city;private String street;// 构造方法、getter/setter省略@Overrideprotected Address clone() {try {return (Address) super.clone();} catch (CloneNotSupportedException e) {throw new AssertionError(); // 不会发生}}
}class Person implements Cloneable {private String name;private int age;private Address address;// 构造方法、getter/setter省略@Overrideprotected Person clone() {try {Person cloned = (Person) super.clone();cloned.address = this.address.clone(); // 深克隆引用对象return cloned;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}// 使用示例
Person original = new Person("张三", 25, new Address("北京", "长安街"));
Person cloned = original.clone();
优点:
- 性能较好
- 可以精确控制克隆过程
缺点:
- 需要为每个类手动实现克隆逻辑
- 当对象图复杂时,实现繁琐
- 需要所有引用对象都实现
Cloneable
3. 使用第三方库
(1) Apache Commons Lang - SerializationUtils
import org.apache.commons.lang3.SerializationUtils;Person original = new Person("张三", 25);
Person cloned = SerializationUtils.clone(original);
(2) JSON序列化方式(如Gson/Jackson)
import com.google.gson.Gson;Gson gson = new Gson();
Person original = new Person("张三", 25);
Person cloned = gson.fromJson(gson.toJson(original), Person.class);
优点:
- 实现简单
- 不要求对象实现
Serializable
或Cloneable
缺点:
- JSON序列化会丢失对象类型信息(如多态)
- 性能比原生序列化更低
- 无法处理循环引用
4. 使用Java深层复制工具库
如Cloner
库(https://github.com/kostaskougios/cloning):
import com.rits.cloning.Cloner;Cloner cloner = new Cloner();
Person original = new Person("张三", 25);
Person cloned = cloner.deepClone(original);
优点:
- 功能强大,可以处理复杂对象图
- 性能较好
- 不需要实现特定接口
缺点:
- 需要引入第三方依赖