在Java中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象复制方式。
-
浅拷贝:
- 浅拷贝创建一个新对象,并将原始对象的字段值复制到新对象中。但如果字段是引用类型,则新对象和原始对象共享相同的引用。
- 在浅拷贝中,对于引用类型的字段,只复制引用而不是创建新的对象。这导致新对象和原始对象指向同一份数据,在修改其中一个对象时,可能会影响到另一个对象。
-
深拷贝:
- 深拷贝创建一个新对象,并将原始对象的字段值复制到新对象中。与浅拷贝不同的是,如果字段是引用类型,则会为该字段创建一个新的对象,而不仅仅是复制引用。
- 在深拷贝中,新对象和原始对象是完全独立的,它们各自拥有自己的数据副本。修改一个对象不会影响到另一个对象。
在Java中实现浅拷贝可以通过clone()
方法来完成,而实现深拷贝则需要自定义实现。
以下是一个示例,演示如何实现浅拷贝和深拷贝:
如果需要直接复制运行
public class CloneTest implements Cloneable{
private String name;
private Age age;
public CloneTest(String name, Age age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
/**
* 浅拷贝
*/
return super.clone();
/**
* 深拷贝
*/
// CloneTest clone = (CloneTest)super.clone();
// clone.age = (Age) age.clone();
//
// return clone;
}
@Override
public String toString() {
return "CloneTest{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Age implements Cloneable {
private int years;
public Age(int years) {
this.years = years;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Age{" +
"years=" + years +
'}';
}
public static void main(String[] args) {
//浅克隆
Age age = new Age(23);
CloneTest cloneTest = new CloneTest("老铁", age);
try {
CloneTest clone = (CloneTest)cloneTest.clone();
//首次输出
System.out.println(clone);
age.years = 12;
//二次输出,更改引用数据类型的值后输出。如果是浅拷贝首次输出和二次输出将是不一样的值,深拷贝者会相同
System.out.println(clone);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
浅拷贝输出第一次和第二次值
深拷贝输出