一、浅拷贝
(1)、定义:复制被复制对象的值,且与被复制对象所引用的对象是同一个对象。
例如:小明的老师是老卢,此时我们(浅拷贝)一份小明,我们就会得到另外一个一模一样的小明(1)(注:这里的小明(1)是方便理解所抽象命名,在实际中name属性是相同的。下同!),而且这个小明(1)的的老师也是老卢。当我们修改小明的老师时,小明(1)的老师也会随着修改。
(2)、代码展示
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("老卢");
Student student1 = new Student();
student1.setName("小明");
student1.setTeacher(teacher);
Student student2 = (Student) student1.clone();
System.out.println("拷贝后");
System.out.println(student2.getName());
System.out.println(student2.getTeacher().getName());
System.out.println("修改老师后");
// 修改老师
teacher.setName("卢姥爷");
System.out.println("student1的teacher为: " + student1.getTeacher().getName());
System.out.println("student2的teacher为: " + student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student implements Cloneable {
private String name;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();//调用重写的方法
return object;
}
}
结果:
拷贝后
小明
老卢
修改老师后
student1的teacher为: 卢姥爷
student2的teacher为: 卢姥爷
分析:可以看到 我们student1的名字我们是设置为“小明”,我们的student2是直接对象拷贝小明,且我们的student2的老师也是指向我们student1的老师“老卢”的。因为,当我们修改teacher这个的name属性为“卢姥爷”时,student1和student2的老师都变成了“卢姥爷”。
两个引用student的两个teacher引用指向的是同一个teacher。所以是浅拷贝。
图解:
二、深拷贝
(1)、定义:深拷贝是一个整体独立的对象拷贝,拷贝属性指向的那些内存。就是说,当对象和它所引用的对象一起被拷贝时就是发生了深拷贝。
例如:就如刚才举例,“小明”的老师是“老卢”,此时我们深拷贝“小明”这一对象得到一个小明(1)的对象,“小明(1)”和他的老师“老卢(1)”是额外占用内存的。
代码:
class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("老卢");
Student student1 = new Student();
student1.setName("小明");
student1.setTeacher(teacher);
Student student2 = (Student) student1.clone();
System.out.println("拷贝后");
System.out.println(student2.getName());
System.out.println(student2.getTeacher().getName());
System.out.println("修改老师的信息后");
// 修改老师的信息
teacher.setName("卢姥爷");
System.out.println("student1的teacher为: " + student1.getTeacher().getName());
System.out.println("student2的teacher为: " + student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student implements Cloneable {
private String name;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
student.setTeacher((Teacher) student.getTeacher().clone());
//这里我们直接将Teacher这个对象都复制的一份
return student;
}
}
结果:
拷贝后
小明
老卢
修改老师的信息后
student1的teacher为: 卢姥爷
student2的teacher为: 老卢
分析:一样的修改student1的teache为“卢姥爷”r时,发现student2的teacher继续为“老卢”。
所以这是深拷贝。
图解:
本文章是作者对老周聊框架的深拷贝与浅拷贝的一些思考以及最后实践得出的结果与讨论。
其中加入作者一些自己的理解,希望帮助大家对深拷贝和浅拷贝有一些认识。