一、拷贝的引入
(1)、引用拷贝
创建一个指向对象的引用变量的拷贝。
public class QuoteCopy { public static void main(String[] args) { Teacher teacher = new Teacher("riemann", 28); Teacher otherTeacher = teacher; System.out.println(teacher); System.out.println(otherTeacher); } } class Teacher { private String name; private int age; public Teacher(String name, int age) { this.name = name; this.age = 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; } }
com.test.Teacher@28a418fc com.test.Teacher@28a418fc
由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher
和otherTeacher
的只是引用而已
,他们都指向了一个相同的对象Teacher(“riemann”,28)
。 这就叫做引用拷贝
。
(2)、对象拷贝
创建对象本身的一个副本。
public class ObjectCopy { public static void main(String[] args) throws CloneNotSupportedException { Teacher teacher = new Teacher("riemann", 28); Teacher otherTeacher = (Teacher) teacher.clone(); System.out.println(teacher); System.out.println(otherTeacher); } } class Teacher implements Cloneable { private String name; private int age; public Teacher(String name, int age) { this.name = name; this.age = 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; } public Object clone() throws CloneNotSupportedException { Object object = super.clone(); return object; } }
com.test.Teacher@28a418fc com.test.Teacher@5305068a
结果分析:由输出结果可以看出,它们的地址是不同的
,也就是说创建了新的对象
, 而不是把原对象的地址赋给了一个新的引用变量,这就叫做对象拷贝。
注:深拷贝和浅拷贝都是对象拷贝
二、浅拷贝
(1)、定义
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。
简而言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
(2)、浅拷贝实例
public class ShallowCopy { public static void main(String[] args) throws CloneNotSupportedException { Teacher teacher = new Teacher(); teacher.setName("riemann"); teacher.setAge(28); Student student1 = new Student(); student1.setName("edgar"); student1.setAge(18); student1.setTeacher(teacher); Student student2 = (Student) 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("jack"); System.out.println("student1的teacher为: " + student1.getTeacher().getName()); System.out.println("student2的teacher为: " + student2.getTeacher().getName()); } } 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; } } class Student 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; } public Object clone() throws CloneNotSupportedException { Object object = super.clone(); return object; } }
-------------拷贝后------------- edgar 18 riemann 28 -------------修改老师的信息后------------- student1的teacher为: jack student2的teacher为: jack
结果分析: 两个引用student1
和student2
指向不同的两个对象,但是两个引用student1
和student2
中的两个teacher
引用指向的是同一个对象,所以说明是浅拷贝
。
三、深拷贝
(1)、定义
深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
简而言之,深拷贝把要复制的对象所引用的对象都复制了一遍。
(2)、深拷贝实例
public class DeepCopy { public static void main(String[] args) throws CloneNotSupportedException { Teacher teacher = new Teacher(); teacher.setName("riemann"); teacher.setAge(28); Student student1 = new Student(); student1.setName("edgar"); student1.setAge(18); student1.setTeacher(teacher); Student student2 = (Student) 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("jack"); System.out.println("student1的teacher为: " + student1.getTeacher().getName()); System.out.println("student2的teacher为: " + student2.getTeacher().getName()); } } 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; } public Object clone() throws CloneNotSupportedException { return super.clone(); } } class Student 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; } public Object clone() throws CloneNotSupportedException { // 浅复制时: // Object object = super.clone(); // return object; // 改为深复制: Student student = (Student) super.clone(); // 本来是浅复制,现在将Teacher对象复制一份并重新set进来 student.setTeacher((Teacher) student.getTeacher().clone()); return student; } }
-------------拷贝后------------- edgar 18 riemann 28 -------------修改老师的信息后------------- student1的teacher为: jack student2的teacher为: riemann
结果分析:
两个引用student1
和student2
指向不同的两个对象,两个引用student1
和student2
中的两个teacher
引用指向的是两个对象,但对teacher
对象的修改只能影响student1
对象,所以说是深拷贝
。
————————————————
版权声明:本文为CSDN博主「老周聊架构」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/riemann_/article/details/87217229