2025年12月21日/ 浏览 35
在Java开发中,对象的拷贝是一个高频操作,但稍不注意就可能引发数据不一致或内存泄漏问题。深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种截然不同的拷贝方式,理解它们的区别和实现方法至关重要。
浅拷贝仅复制对象本身及其基本类型字段,而引用类型的字段(如数组、集合或其他对象)则直接复制引用地址。这意味着原对象和拷贝对象共享同一块堆内存数据,修改任一方的引用字段都会影响另一方。
实现方法:
– 实现Cloneable接口并重写clone()方法(默认浅拷贝)。
java
class Student implements Cloneable {
private String name;
private int age;
private Address address; // 引用类型
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 默认浅拷贝
}
}
风险示例:
若修改拷贝后的Student对象的address字段,原对象的address也会同步变化,可能导致业务逻辑错误。
深拷贝会递归复制所有字段及其引用的对象,生成一个完全独立的新对象。虽然安全性高,但实现复杂且可能影响性能。
实现方法:
– 手动递归克隆:为所有引用类型字段实现clone()方法。
java
class Student implements Cloneable {
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Student cloned = (Student) super.clone();
cloned.address = (Address) address.clone(); // 递归克隆引用对象
return cloned;
}
}
ObjectOutputStream和ObjectInputStream实现(需所有对象实现Serializable接口)。
public static T deepCopy(T obj) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
}
| 特性 | 浅拷贝 | 深拷贝 |
|—————|—————————|—————————|
| 引用处理 | 共享引用对象 | 创建全新引用对象 |
| 性能 | 高效(仅复制一层) | 较低(递归或IO操作) |
| 安全性 | 低(易产生副作用) | 高(完全隔离) |
| 适用场景 | 不可变对象或临时拷贝 | 需严格隔离的配置、缓存等 |
String)或明确无需修改的场景。 通过合理选择拷贝策略,可以显著提升程序的健壮性和可维护性。