Java深拷贝和浅拷贝
深拷贝和浅拷贝都是对象拷贝
浅拷贝
:在进行对象拷贝时,仅仅只拷了一层对象,而其子对象则不会拷贝,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象
public class ShallowCopy {
public static void main(String[] args) {
Parents parents = new Parents();
parents.setName("kong");
parents.setAge("34");
Child child = new Child();
child.setUsername("Dream");
child.setId(1);
child.setParents(parents);
Child child2 = (Child) child.clone();
System.out.println("拷贝后");
System.out.println(child2.getUsername());
System.out.println(child2.getId());
System.out.println(child2.getParents().getName());
System.out.println(child2.getParents().getAge());
System.out.println("修改父母的信息后-------------");
// 修改父母的信息
parents.setName("Jam");
System.out.println(child.getParents().getName());
System.out.println(child2.getParents().getName());
}
}
class Parents implements Cloneable{
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Parents{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
class Child implements Cloneable{
private String username;
private int id;
private Parents parents;
public Parents getParents() {
return parents;
}
public void setParents(Parents parents) {
this.parents = parents;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//浅拷贝
@Override
public Child clone() {
try {
return (Child) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
远行结果:
分析:以上代码可以看出,child和child2不是同一个对象,但是当修改父母的信息时,再输出Child类的parents属性值时,两个不同的对象的parents属性值都被修改了。
画图分析:
深拷贝
深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。深拷贝把要复制的对象所引用的对象都复制了一遍。
第一种方法:
package Copy;
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Parents parents = new Parents();
parents.setName("kong");
parents.setAge("34");
Child child = new Child();
child.setUsername("Dream");
child.setId(1);
child.setParents(parents);
Child child2 = (Child) child.clone();
System.out.println("拷贝后");
System.out.println(child2.getUsername());
System.out.println(child2.getId());
System.out.println(child2.getParents().getName());
System.out.println(child2.getParents().getAge());
System.out.println("修改父母的信息后-------------");
// 修改父母的信息
parents.setName("Jam");
System.out.println(child.getParents().getName());
System.out.println(child2.getParents().getName());
}
}
class Parents implements Cloneable{
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Parents{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
@Override
public Parents clone() {
try {
// TODO: copy mutable state here, so the clone can't change the internals of the original
return (Parents) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
class Child implements Cloneable{
private String username;
private int id;
private Parents parents;
public Parents getParents() {
return parents;
}
public void setParents(Parents parents) {
this.parents = parents;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// @Override
// public Child clone() {
// try {
// // TODO: copy mutable state here, so the clone can't change the internals of the original
// return (Child) super.clone();
// } catch (CloneNotSupportedException e) {
// throw new AssertionError();
// }
// }
public Object clone() throws CloneNotSupportedException {
// 改为深复制
Child child2 = (Child) super.clone();
// 本来是浅复制,现在将Parents对象复制一份并重新set进来
child2.setParents(child2.getParents().clone());
return child2;
}
}
远行结果:
分析:两个引用child和child2指向不同的两个对象,两个引用child和child2中的两个parents引用指向的是两个对象,但对parents对象的修改只能影响child2对象,所以说是深拷贝。
画图分析:
第二种方法:类实现Serializable接口
代码如下:
package Copy;
import java.io.*;
public class ShallowCopy {
public static void main(String[] args) throws Exception {
Parents parents = new Parents();
parents.setName("kong");
parents.setAge("34");
Child child = new Child();
child.setUsername("Dream");
child.setId(1);
child.setParents(parents);
Child child2 = (Child) child.deepClone();
System.out.println("拷贝后");
System.out.println(child2.getUsername());
System.out.println(child2.getId());
System.out.println(child2.getParents().getName());
System.out.println(child2.getParents().getAge());
System.out.println("修改父母的信息后-------------");
// 修改父母的信息
parents.setName("Jam");
System.out.println(child.getParents().getName());
System.out.println(child2.getParents().getName());
}
}
class Parents implements Serializable {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Parents{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
// @Override
// public Parents clone() {
// try {
// // TODO: copy mutable state here, so the clone can't change the internals of the original
// return (Parents) super.clone();
// } catch (CloneNotSupportedException e) {
// throw new AssertionError();
// }
// }
}
class Child implements Serializable{
private String username;
private int id;
private Parents parents;
public Parents getParents() {
return parents;
}
public void setParents(Parents parents) {
this.parents = parents;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// @Override
// public Child clone() {
// try {
// // TODO: copy mutable state here, so the clone can't change the internals of the original
// return (Child) super.clone();
// } catch (CloneNotSupportedException e) {
// throw new AssertionError();
// }
// }
// public Object clone() throws CloneNotSupportedException {
// // 改为深复制
// Child child2 = (Child) super.clone();
// // 本来是浅复制,现在将Parents对象复制一份并重新set进来
// child2.setParents(child2.getParents().clone());
// return child2;
// }
public Object deepClone() throws Exception {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
远行结果: