Deep copy of clone () in Java
Show the shortest copy: for non-basic data types, after the clone, the two pointers point to the same memory space, so it is only a shortest copy, so if you operate on an object, the other content also changes, which is obviously unreasonable. Each object should save its own data.
So we need to make a deep copy!
Example of shortest copy and deep copy:
Import java. util. vector; public class Student implements Cloneable {private int id; private String name; private Vector courses; public Student () {try {Thread. sleep (1, 1000); System. out. println ("Student Construnctor called");} catch (InterruptedException e) {e. printStackTrace () ;}} public int getId () {return id;} public void setId (int id) {this. id = id;} public String getName () {return name;} public void setName (String name) {this. name = name;} public Vector getCourses () {return courses;} public void setCourses (Vector courses) {this. courses = courses;} public Student newInstance () {// use clone () to create an object, and copy try {return (Student) this. clone ();} catch (CloneNotSupportedException e) {e. printStackTrace ();} return null;} public Student deepClone () {// use clone () to create an object, and copy try {Student cloning = (Student) super. clone (); // Student cloning = (Strdent) this. clone (); // cloning is equivalent to the previous statement. courses = new Vector (); // key point: a non-basic data type space needs to be opened up with a new return cloning;} catch (CloneNotSupportedException e) {e. printStackTrace ();} return null ;}}
import java.util.Vector;public class Test {public static void main(String[] args) {// TODO Auto-generated method stubStudent stu1 = null;shallowCopyDemo(stu1);System.out.println("----- ----- -----I'm cut-off rule----- ----- -----");deepCopyDemo(stu1);}public static void shallowCopyDemo(Student stu1) {stu1=new Student();Vector cs=new Vector();cs.add("Java");stu1.setId(1);stu1.setName("Tom");stu1.setCourses(cs);Student stu2=stu1.newInstance();stu2.setId(2);stu2.setName("Mary");stu2.getCourses().add("C#");System.out.println("stu1'name:"+stu1.getName());System.out.println("stu2'name:"+stu2.getName());System.out.println(stu1.getCourses()==stu2.getCourses());System.out.println(stu1.getName + "'s course: " + stu1.getCourses());System.out.println(stu2.getName + "'s course: " + stu2.getCourses());}public static void deepCopyDemo(Student stu1) {stu1=new Student();Vector cs=new Vector();cs.add("Java");stu1.setId(1);stu1.setName("Tom");stu1.setCourses(cs);Student stu2=stu1.deepClone();stu2.setId(2);stu2.setName("Mary");stu2.getCourses().add("C#");System.out.println("stu1'name:"+stu1.getName());System.out.println("stu2'name:"+stu2.getName());System.out.println(stu1.getCourses()==stu2.getCourses());System.out.println(stu1.getName + "'s course: " + stu1.getCourses());System.out.println(stu2.getName + "'s course: " + stu2.getCourses());}}
Output result:
Student Construnctor called
Stu1 'name: Tom
Stu2 'name: Mary
True
Tom's course: [Java, C #]
Mary's course: [Java, C #]
----- I'm cut-off rule ---------------
Student Construnctor called
Stu1 'name: Tom
Stu2 'name: Mary
False
Tom's course: [Java]
Mary's course: [C #]
From the results, we can see that when calling the shortest COPY method to add course C # to Mary, C # exists in Tom's course, and Tom's Java exists in Mary's course, and stu1.getCourses () = stu2.getCourses () returns "true", indicating that the course attribute of the two points to the same memory. In the second case, we have opened up a space for the copied Mary course cloning. courses = new Vector (), so Tom and Mary manipulate different Vector memory, which is naturally different.
In the above example, the deep copy deepClone () and the shallow copy newInstance () functions are all written by ourselves, so the Student cloning = (Student) super of deepClone. clone () and Student cloning = (Strdent) this. clone () is feasible. In addition, we can directly override the clone () function of this class so that we can only use Student cloning = (Student) super. clone (). The overwrite code is as follows:
Public Object clone () {// override clone (), deep copy try {Student cloning = (Student) super. clone (); cloning. courses = new Vector (); // key point: a non-basic data type space needs to be opened up with a new return cloning;} catch (CloneNotSupportedException e) {e. printStackTrace ();} return null ;}
Student cloning = (Strdent) this. the reason for clone () is that we are overwriting the clone () method of this class. If we call the function of this class again, that is: this. clone () is equivalent to infinite loop of wireless recursion, And will crash in the end. So here we can only call the function of the parent class, namely: super. clone ().
Therefore, either give your own deep copy function a name, or overwrite the clone () method of the class. You can choose one, but the key to both is-For non-basic data types, a new space is required.