Java对象克隆:从浅到深的奥秘
浅克隆与深克隆在Java中的应用及区别
核心概念
- 浅克隆
复制对象时仅克隆基本数据类型字段,引用类型字段共享原对象引用。实现方式:
class Person implements Cloneable {String name;Address address; // 引用类型字段@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 默认浅克隆}
}class Address {String city;
}
2.深克隆
完全独立复制对象及其关联对象:
class DeepPerson implements Cloneable {String name;Address address;@Overrideprotected Object clone() throws CloneNotSupportedException {DeepPerson cloned = (DeepPerson) super.clone();cloned.address = new Address(); // 新建独立地址对象cloned.address.city = this.address.city;return cloned;}
}
应用场景对比
特性 | 浅克隆 | 深克隆 |
---|---|---|
内存消耗 | 低(共享引用) | 高(创建新对象) |
数据隔离性 | 弱(修改影响原对象) | 强(完全隔离) |
实现复杂度 | 简单(自动实现) | 复杂(需递归处理) |
适用场景 | 不可变对象/简单结构 | 复杂对象层级/需要隔离修改 |
深度克隆进阶实现
- 序列化方案(需实现Serializable接口)
import java.io.*;class SerialCloneable implements Serializable {public Object deepClone() throws IOException, ClassNotFoundException {try (ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(this);try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis)) {return ois.readObject();}}}
}
2.嵌套对象克隆测试
public static void main(String[] args) throws Exception {// 浅克隆测试Address addr = new Address("Beijing");Person original = new Person("Alice", addr);Person cloned = (Person) original.clone();cloned.address.city = "Shanghai";System.out.println(original.address.city); // 输出"Shanghai"// 深克隆测试DeepPerson deepOriginal = new DeepPerson("Bob", new Address("Guangzhou"));DeepPerson deepClone = (DeepPerson) deepOriginal.clone();deepClone.address.city = "Shenzhen";System.out.println(deepOriginal.address.city); // 保持"Guangzhou"
}
核心差异总结
-
对象关系拓扑:
- 浅克隆:生成对象图与原对象共享叶节点
- 深克隆:构建完全独立的对象树
-
内存模型表现:
3.修改传播特性:
最佳实践建议
- 优先考虑不可变对象设计
- 复杂对象推荐使用深克隆框架(如Apache Commons Lang3的SerializationUtils)
- 对于循环引用结构,需实现引用追踪机制
- 注意克隆过程中静态字段的处理