克隆
拷贝与克隆
-
拷贝:此时,变量dogA和dogB指向着同一个对象,任何一个变量改变都会影响另一个变量
-
Dog dogA = new Dod(); Dog dogB = dogA;
-
-
克隆
-
浅拷贝:默认的克隆操作是“浅拷贝”,浅拷贝并没有克隆对象中引用的其他对象
package com.kelvin.clone_test; public class Student implements Cloneable{ // 需要实现标记接口Cloneable才可以用Clone方法 String name; int age; Teacher teacher; /*省略了get set toString 和 构造方法*/ // 浅拷贝(为了使该类以外的类(ShallowCopyTest)也能对Student进行clone,需要将该方法变为public) // 原Object中的clone为protected public Student clone() throws CloneNotSupportedException { return (Student) super.clone(); } // 深拷贝 public Student hardClone () throws CloneNotSupportedException { Student cStudent = (Student) super.clone(); cStudent.teacher = this.teacher.clone(); return cStudent; } }
package com.kelvin.clone_test; public class Teacher implements Cloneable{ String name; int age; /*省略了get set toString 和 构造方法*/ // Student的深拷贝拷贝需要克隆Teacher所以需要将方法变为public public Teacher clone() throws CloneNotSupportedException { return (Teacher) super.clone(); } }
package com.kelvin.clone_test; // 浅拷贝 public class ShallowCopyTest { public static void main(String[] args) throws CloneNotSupportedException { Teacher teacher = new Teacher("XinYuan", 22); Student kelvin = new Student("Kelvin.Su", 23, teacher); Student cKelvin = (Student) kelvin.clone(); // 克隆后没有进行别的操作,这里的输出是一样的 System.out.println(kelvin); System.out.println(cKelvin + "\n"); // 做一些修改来验证浅拷贝的特性 kelvin.setName("SuKaiWen"); teacher.setName("LiuXinYuan"); // 可以看到现在kelvin与cKelvin是两个不同的对象,对Kelvin修改name字段并不会影响到cKelvin // 但是kelvin与cKelvin的teacher字段指向着同一个对象,对teacher做修改,kelvin与cKelvin的teacher字段都会被修改 System.out.println(kelvin); System.out.println(cKelvin); /* 输出: Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}} Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}} Student{name='SuKaiWen', age=23, teacher=Teacher{name='LiuXinYuan', age=22}} Student{name='Kelvin.Su', age=23, teacher=Teacher{name='LiuXinYuan', age=22}} */ } }
-
深拷贝
package com.kelvin.clone_test; public class DeepCopyTest { public static void main(String[] args) throws CloneNotSupportedException { Teacher teacher = new Teacher("XinYuan", 22); Student kelvin = new Student("Kelvin.Su", 23, teacher); Student cKelvin = (Student) kelvin.hardClone(); // 克隆后没有进行别的操作,这里的输出是一样的 System.out.println(kelvin); System.out.println(cKelvin + "\n"); // 做一些修改来验证浅拷贝的特性 kelvin.setName("SuKaiWen"); teacher.setName("LiuXinYuan"); // 经过深拷贝的Student修改kelvin的teacher字段并不会改变cKelvin的teacher字段 System.out.println(kelvin); System.out.println(cKelvin); /* 输出: Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}} Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}} Student{name='SuKaiWen', age=23, teacher=Teacher{name='LiuXinYuan', age=22}} Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}} */ } }
// 深拷贝 public Student hardClone () throws CloneNotSupportedException { Student cStudent = (Student) super.clone(); cStudent.teacher = this.teacher.clone(); return cStudent; }
-
Array.copyOf()是浅拷贝
public class CopyOfTest { public static void main(String[] args) { Teacher teacher = new Teacher("XinYuan", 22); Student kelvin = new Student("Kelvin.Su", 23, teacher); Student[] students = new Student[1]; students[0] = kelvin; Student[] cStudents = Arrays.copyOf(students, students.length); // Arrays.copyOf后没有进行别的操作,这里的输出是一样的 System.out.println(students[0]); System.out.println(cStudents[0]); // 做一些修改来验证浅拷贝的特性 kelvin.setName("SuKaiWen"); teacher.setName("LiuXinYuan"); // 可以看到现在students[0]与cStudents[0]是两个不同的对象,对students[0]修改name字段并不会影响到cStudents[0] // 但是students[0]与cStudents[0]的teacher字段指向着同一个对象,对teacher做修改,students[0]与cStudents[0]的teacher字段都会被修改 System.out.println(students[0]); System.out.println(cStudents[0]); } }
-