浅拷贝和深拷贝是两种不同的对象复制方式,主要区别在于它们如何处理对象内部的引用类型字段。
浅拷贝 (Shallow Copy)
特点:
只复制对象本身(基本类型字段)和对象中的引用(地址)
不复制引用指向的实际对象
原始对象和拷贝对象共享内部引用对象
示例:
class Person {String name;Address address; // 引用类型// 浅拷贝方法public Person shallowCopy() {Person copy = new Person();copy.name = this.name; // 基本类型或String的复制copy.address = this.address; // 只是复制引用return copy;}
}
结果:
修改拷贝对象的
address
会影响原始对象,因为它们引用同一个Address对象
深拷贝 (Deep Copy)
特点:
复制对象本身及其所有引用的对象
递归复制所有引用对象直到基本类型
原始对象和拷贝对象完全独立,不共享任何引用
示例:
class Person {String name;Address address;// 深拷贝方法public Person deepCopy() {Person copy = new Person();copy.name = this.name;copy.address = new Address(this.address.street, this.address.city); // 创建新对象return copy;}
}
结果:
修改拷贝对象的
address
不会影响原始对象,因为它们引用不同的Address对象
对比表格
特性 | 浅拷贝 | 深拷贝 |
---|---|---|
复制内容 | 对象本身和引用地址 | 对象本身和所有引用对象 |
内存消耗 | 较少 | 较多 |
性能 | 较快 | 较慢 |
独立性 | 不独立(共享引用对象) | 完全独立 |
实现复杂度 | 简单 | 复杂(需要递归复制所有引用对象) |
实际应用场景
使用浅拷贝:
当对象内部引用是不可变的(如String)
当明确需要共享某些引用对象时
性能要求高且不需要完全独立的对象时
使用深拷贝:
需要完全独立的对象副本时
当对象包含可变引用对象且不希望共享时
在多线程环境中需要安全地共享数据时
Java中的实现方式
浅拷贝:
实现
Cloneable
接口并重写clone()
方法手动复制字段
深拷贝:
递归实现
clone()
方法使用序列化和反序列化
使用第三方库如Apache Commons Lang的
SerializationUtils.clone()
使用复制构造函数或工厂方法
// 使用序列化实现深拷贝
public static <T extends Serializable> T deepCopy(T object) {try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(object);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);return (T) ois.readObject();} catch (Exception e) {throw new RuntimeException(e);}
}