Java中浅拷贝和深拷贝的区别
深拷贝和浅拷贝的区别
浅拷贝:被拷贝的对象的所有属性值都与原来的对象相同,而对象的所有属性引用仍然指向原来的属性所指向的内存地址。需要注意的是cloneObj == obj 返回的是false,所以使用的Object的clone()是浅拷贝。
深拷贝:被拷贝的对象的所有属性值都与原来的对象相同,而对象的所有属性的引用都指向新的克隆出来的属性的内存地址。
浅拷贝的实现方式
public class Test implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
深拷贝的实现方式
深拷贝的实现方式一般有三种,第一种是使用构造器来实现,这个先不说
第二种是使用clone()方法来实现
public class Test implements Cloneable {
private SubTest subTest;
@Override
protected Object clone() {
Object obj = null;
try {
obj = super.clone();
Test cloneTest = (Test) obj;
Object subObj = cloneTest.subTest.clone();
SubTest cloneSubTest = (SubTest) subObj;
cloneTest.setSubTest(cloneSubTest);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
public void setSubTest(SubTest subTest) {
this.subTest = subTest;
}
}
第三种方法是使用序列化来进行深拷贝
SubTest
import java.io.Serializable;
public class SubTest implements Cloneable, Serializable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Test
public class Test implements Cloneable, Serializable {
private SubTest subTest;
// 使用clone()进行深拷贝
@Override
protected Object clone() {
Object obj = null;
try {
obj = super.clone();
Test cloneTest = (Test) obj;
Object subObj = cloneTest.subTest.clone();
SubTest cloneSubTest = (SubTest) subObj;
cloneTest.setSubTest(cloneSubTest);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
// 使用序列化方式来实现深拷贝
public Object deepClone() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
public void setSubTest(SubTest subTest) {
this.subTest = subTest;
}
public SubTest getSubTest() {
return subTest;
}
}
