Java中的深拷贝与浅拷贝
字数 539 2025-11-04 08:34:41
Java中的深拷贝与浅拷贝
一、概念描述
深拷贝和浅拷贝是对象复制的两种方式。浅拷贝只复制对象本身和其基本类型字段,但引用类型字段仍指向原对象的引用地址;深拷贝则会递归复制所有引用类型字段指向的对象,创建一个完全独立的新对象。
二、浅拷贝详解
-
实现方式
- 实现
Cloneable接口 - 重写
Object.clone()方法(默认为protected) - 调用
super.clone()完成基础复制
- 实现
-
代码示例
class Person implements Cloneable {
String name;
Address address; // 引用类型字段
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // 浅拷贝
}
}
- 问题演示
Person p1 = new Person("Tom", new Address("北京"));
Person p2 = (Person) p1.clone();
p2.address.city = "上海"; // p1的address也会被修改!
System.out.println(p1.address.city); // 输出"上海"
三、深拷贝实现方式
- 手动递归克隆
class Address implements Cloneable {
String city;
// 重写clone方法
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable {
String name;
Address address;
@Override
public Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) this.address.clone(); // 关键步骤
return cloned;
}
}
- 序列化方式
public class DeepCopyUtil {
public static <T> 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();
}
}
// 要求所有涉及类实现Serializable接口
四、对比总结
| 特性 | 浅拷贝 | 深拷贝 |
|---|---|---|
| 对象独立性 | 部分独立 | 完全独立 |
| 引用类型处理 | 共享引用 | 创建新对象 |
| 性能开销 | 小 | 大(尤其序列化方式) |
| 实现复杂度 | 简单 | 复杂 |
五、注意事项
- 循环引用问题:深拷贝时需要处理对象间的循环引用
- 性能考虑:对于复杂对象图,深拷贝可能带来较大开销
- 推荐方案:考虑使用不可变对象避免拷贝需求,或使用拷贝构造器替代Cloneable接口
六、实际应用场景
- 浅拷贝:配置对象共享基础配置时
- 深拷贝:需要完全隔离的上下文环境(如会话复制、事务回滚)