Deep copy (deep copy) and shallow copy (shallow copy) are two relatively common concepts, especially in the C++ language. If you don't understand it, you will have problems when deleting, but fortunately we are using Java here. . Although Java automatically manages the recycling of objects, we still have to pay enough attention to deep copy (deep copy) and shallow copy (shallow copy), because sometimes these two concepts often bring us a lot of confusion.
Shallow copy means that when copying an object, only the object itself (including the basic variables in the object) is copied, but the object pointed to by the reference contained in the object is not copied. A deep copy not only copies the object itself, but also copies all objects pointed to by references contained in the object. For example, to make it clearer: object A1 contains a reference to B1, and B1 contains a reference to C1. Shallow copy A1 to get A2. A2 still contains a reference to B1, and B1 still contains a reference to C1. Deep copy is the recursion of shallow copy. Deep copy A1 to get A2. A2 contains a reference to B2 (copy of B1), and B2 contains a reference to C2 (copy of C1).
If the clone() method is not rewritten, the object obtained by calling this method is a shallow copy. Let's focus on deep copy below.
Run the following program to take a look at the shallow copy:
class Professor0 implements Cloneable { String name; int age; Professor0(String name, int age) { this.name = name; this.age = age; } public Object clone() throws CloneNotSupportedException { return super.clone(); } } class Student0 implements Cloneable { String name; // Constant object. int age; Professor0 p;//The reference values of student 1 and student 2 are the same. Student0(String name, int age, Professor0 p) { this.name = name; this.age = age; this.p = p; } public Object clone() { Student0 o = null; try { o = (Student0) super .clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString()); } return o; } } public class ShallowCopy { public static void main(String[] args) { Professor0 p = new Professor0("wangwu", 50); Student0 s1 = new Student0("zhangsan", 18, p); Student0 s2 = (Student0) s1.clone(); s2. p.name = "lisi"; s2.p.age = 30; s2.name = "z"; s2.age = 45; System.out.println("Name of student s1:" + s1.name + "/n Name of professor of student s1:" + s1.p.name + "," + "/n Age of professor of student s1" + s1 .p.age);//Professor of student 1} }
s2 has changed, but s1 has also changed, proving that p of s1 and p of s2 point to the same object. This is not the case in our actual needs, so we need a deep copy:
class Professor implements Cloneable { String name; int age; Professor(String name, int age) { this.name = name; this.age = age; } public Object clone() { Object o = null; try { o = super. clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString()); } return o; } } class Student implements Cloneable { String name; int age; Professor p; Student(String name, int age, Professor p) { this.name = name; this.age = age; this.p = p; } public Object clone() { Student o = null; try { o = (Student) super.clone(); } catch (CloneNotSupportedException e) { System.out.println(e.toString()); } op = (Professor) p.clone(); return o; } } public class DeepCopy { public static void main(String args[]) { long t1 = System.currentTimeMillis(); Professor p = new Professor("wangwu", 50); Student s1 = new Student("zhangsan", 18, p); Student s2 = (Student) s1.clone(); s2.p.name = "lisi"; s2.p.age = 30; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // Student 1’s professor does not change. long t2 = System.currentTimeMillis(); System.out.println(t2-t1); } }
Of course, we also have a deep copy method, which is to serialize the object:
import java.io.*; //Serialization is time-consuming class Professor2 implements Serializable { /** * */ private static final long serialVersionUID = 1L; String name; int age; Professor2(String name, int age) { this. name = name; this.age = age; } } class Student2 implements Serializable { /** * */ private static final long serialVersionUID = 1L; String name;// constant object. int age; Professor2 p;//The reference values of student 1 and student 2 are the same. Student2(String name, int age, Professor2 p) { this.name = name; this.age = age; this.p = p; } public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException { // Write the object to the stream In ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); // Read ByteArrayInputStream from the stream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return (oi.readObject()); } } public class DeepCopy2 { /** * @param args */ public static void main(String[] args) throws OptionalDataException, IOException, ClassNotFoundException { long t1 = System.currentTimeMillis(); Professor2 p = new Professor2("wangwu", 50); Student2 s1 = new Student2("zhangsan", 18, p); Student2 s2 = (Student2) s1.deepClone (); s2.p.name = "lisi"; s2.p.age = 30; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // Student 1's professor does not change. long t2 = System.currentTimeMillis(); System.out.println(t2-t1); } }
However, serialization is very time-consuming. In some frameworks, we can feel that they often serialize objects and then transfer them, which takes a lot of time.