一、浅拷贝
- 概念:
拷贝对象和原始对象的引用类型引用同一个对象。浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝。
2.实例:
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("riemann");
teacher.setAge(18);
Student2 student1 = new Student2();
student1.setName("edgar");
student1.setAge(15);
student1.setTeacher(teacher);
Student2 student2 = (Student2) student1.clone();
System.out.println("拷贝后:");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("修改老师的信息后::");
teacher.setName("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
static class Teacher implements Cloneable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
static class Student2 implements Cloneable{
private String name;
private int age;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}
- 结果分析:
两个引用student1和student2指向两个不同的对象,但是两个引用student1和student2中的teacher引用指向的是同一个对象,所以说明是浅拷贝。
二、深拷贝
- 概念:
拷贝对象和原始对象的引用类型引用不同对象。深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝。
2.实例:
public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher2 teacher = new Teacher2();
teacher.setName("riemann");
teacher.setAge(27);
Student3 student1 = new Student3();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher);
Student3 student2 = (Student3) student1.clone();
System.out.println("拷⻉后");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("修改⽼师的信息后——————");
teacher.setName("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
static class Teacher2 implements Cloneable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class Student3 implements Cloneable{
private String name;
private int age;
private Teacher2 teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher2 getTeacher() {
return teacher;
}
public void setTeacher(Teacher2 teacher) {
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student3 student = (Student3) super.clone();
student.setTeacher((Teacher2) student.getTeacher().clone());
return student;
}
}
}
- 结果分析:
两个引用student1和student2指向两个不同的对象,两个引用student1和student2中的teacher引用指向的是两个对象,但是对teacher对象的修改只能影响到student1对象,所以说是深拷贝。
补充:
- 深克隆的实现就是在引用类型所在的类实现 Cloneable 接口,并使用 public 访问修饰符重写 clone 方法。
- Java 中定义的 clone 没有深浅之分,都是统一的调用 Object 的 clone 方法。为什么会有深克隆的概念?是由于我们在实现的过程中刻意的嵌套了 clone 方法的调用。也就是说深克隆就是在需要克隆的对象类型的类中重新实现克隆方法 clone()。