深拷贝和浅拷贝是对象复制的两种不同方式,主要区别在于它们如何处理对象内部的引用类型字段。
浅拷贝 (Shallow Copy)
特点:
-
只复制对象本身,不复制对象内部的引用类型成员变量
-
对于基本数据类型字段,直接复制值
-
对于引用类型字段,只复制引用地址(即新旧对象共享同一内部对象)
结果:
-
原始对象和拷贝对象的引用类型字段指向同一个内存地址
-
修改其中一个对象的引用类型字段会影响另一个对象
实现方式:
-
Java中默认的
clone()
方法实现的是浅拷贝 -
直接赋值(对于引用类型)
class Person implements Cloneable {
String name;
Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 浅拷贝
}
}
深拷贝 (Deep Copy)
特点:
-
不仅复制对象本身,还会递归复制对象内部的所有引用类型成员变量
-
创建全新的对象及其所有引用的对象
-
新旧对象完全独立,不共享任何引用
结果:
-
原始对象和拷贝对象的所有层级都是独立的对象
-
修改其中一个对象不会影响另一个对象
实现方式:
-
重写
clone()
方法并递归调用引用对象的clone()
-
通过序列化和反序列化
-
使用复制构造函数或工厂方法
class Person implements Cloneable {
String name;
Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone(); // 深拷贝关键
return cloned;
}
}
对比表格
特性 | 浅拷贝 | 深拷贝 |
---|---|---|
复制内容 | 只复制对象本身 | 复制对象及其引用的所有对象 |
引用类型字段 | 共享同一对象 | 创建新对象 |
内存消耗 | 较少 | 较多 |
性能 | 较快 | 较慢 |
独立性 | 修改引用字段会影响原对象 | 完全独立,互不影响 |
实现复杂度 | 简单(默认clone) | 复杂(需要递归处理所有引用对象) |
使用场景
-
浅拷贝适用:对象内部只有基本类型或不可变对象(如String),或明确需要共享引用时
-
深拷贝适用:对象包含可变引用类型字段,且需要完全独立的副本时
注意:Java中String
虽然是引用类型,但由于其不可变性,在浅拷贝中可以视为值类型处理。