Deep Copy (tiefe Kopie) und flache Kopie (flache Kopie) sind zwei relativ häufige Konzepte, insbesondere in der Sprache C++. Wenn Sie es nicht verstehen, werden Sie beim Löschen Probleme haben, aber zum Glück verwenden wir hier Java. Obwohl Java das Recycling von Objekten automatisch verwaltet, müssen wir der tiefen Kopie (Deep Copy) und der flachen Kopie (flache Kopie) dennoch genügend Aufmerksamkeit schenken, da diese beiden Konzepte manchmal oft große Verwirrung stiften.
Flaches Kopieren bedeutet, dass beim Kopieren eines Objekts nur das Objekt selbst (einschließlich der Basisvariablen im Objekt) kopiert wird, das Objekt, auf das die im Objekt enthaltene Referenz verweist, jedoch nicht kopiert wird. Eine tiefe Kopie kopiert nicht nur das Objekt selbst, sondern auch alle Objekte, auf die durch im Objekt enthaltene Referenzen verwiesen wird. Um es klarer zu machen: Objekt A1 enthält eine Referenz auf B1 und B1 enthält eine Referenz auf C1. Kopieren Sie A1 flach, um A2 zu erhalten. A2 enthält immer noch einen Verweis auf B1, und B1 enthält immer noch einen Verweis auf C1. Eine tiefe Kopie ist die Rekursion der flachen Kopie A1, um A2 einen Verweis auf B2 (Kopie von B1) zu erhalten, und B2 enthält einen Verweis auf C2 (Kopie von C1).
Wenn die clone()-Methode nicht neu geschrieben wird, ist das durch den Aufruf dieser Methode erhaltene Objekt eine flache Kopie. Konzentrieren wir uns weiter unten auf die tiefe Kopie.
Führen Sie das folgende Programm aus, um einen Blick auf die flache Kopie zu werfen:
class Professor0 implementiert Cloneable { String name; int age) { this.name = name this.age = age; Klasse Student0 implementiert Cloneable { String name; // Konstantes Objekt. int age; Professor0 p;//Die Referenzwerte von Schüler 1 und Schüler 2 sind gleich. Student0(String name, int age, Professor0 p) { this.name = name; this.age = this.p = p } public Object clone() { o = null; .clone(); } Catch (CloneNotSupportedException e) { System.out.println(e.toString()); public class ShallowCopy { public static void main(String[] args) { Professor0 p = new Professor0("wangwu", 50); Student0 s1 = new Student0("zhangsan", 18, p); p.name = "lisi"; s2.p.age = 30; s2.name = "z"; System.out.println("Name des Studenten s1:" + s1.name + "/n Name des Professors des Studenten s1:" + s1.p.name + "," + "/n Alter des Professors des Studenten s1" + s1 .p.age);//Professor von Student 1} }
s2 hat sich geändert, aber auch s1 hat sich geändert, was beweist, dass p von s1 und p von s2 auf dasselbe Objekt zeigen. Dies ist bei unserem tatsächlichen Bedarf nicht der Fall, daher benötigen wir eine tiefe Kopie:
Klasse Professor implementiert Cloneable { String name; int age) { this.name = name = age; { Object o = null; clone(); } Catch (CloneNotSupportedException e) { System.out.println(e.toString() } return o; int age; Professor p; Student(String name, int age, Professor p) { this.name = this.p = p } public Object clone() { Student o = null; 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(); = new Student("zhangsan", 18, p); Student s2 = (Student) s1.clone(); s2.p.age = 30; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // Der Professor von Student 1 ändert sich nicht. long t2 = System.currentTimeMillis(); System.out.println(t2-t1);
Natürlich haben wir auch eine Deep-Copy-Methode, bei der das Objekt serialisiert wird:
import java.io.*; //Serialisierung ist zeitaufwändig. Klasse Professor2 implementiert Serialisierbar { /** * */ private static final long serialVersionUID = 1L; name = name; this.age = age; } } class Student2 implementiert Serializable { /** * */ private static final long serialVersionUID = 1L; konstantes Objekt. int age; Professor2 p;//Die Referenzwerte von Student 1 und Student 2 sind gleich. Student2(String name, int age, Professor2 p) { this.name = name; this.age = age this.p = p } public Object deepClone() throws IOException, OptionalDataException { // Schreiben Sie das Objekt in das stream In ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); // ByteArrayInputStream aus dem Stream lesen bi = new ByteArrayInputStream(bo.toByteArray()); oi = new ObjectInputStream(bi) } 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); (); s2.p.name = "lisi"; System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // Der Professor von Student 1 ändert sich nicht. long t2 = System.currentTimeMillis(); System.out.println(t2-t1);
Allerdings ist die Serialisierung sehr zeitaufwändig. Wir haben das Gefühl, dass sie oft Objekte serialisieren und dann übertragen, was viel Zeit in Anspruch nimmt.