Heim  >  Artikel  >  Java  >  Ausführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werden

Ausführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werden

Y2J
Y2JOriginal
2017-04-26 10:05:301231Durchsuche

Dieser Artikel ist eine detaillierte Analyse und Einführung in die Methode des serialisierten Zugriffs, um ein tiefes Klonen von Java-Objekten zu realisieren. Freunde, die es benötigen, können darauf verweisen

Wir wissen, dass es sich bei Java um einen Nicht-Prototyp-Typ handelt Nachdem die Objektreferenz einer anderen Objektreferenz zugewiesen wurde, verweisen die beiden Referenzen auf dasselbe Objekt, z. B.:

Der Code lautet wie folgt:

public class DeepCloneTest { private class CloneTest {  private Long myLong = new Long(1); } public static void main(String args[]) {  new DeepCloneTest().Test(); } public void Test() {  CloneTest ct1 = new CloneTest();  CloneTest ct2 = ct1;  // to see if ct1 and ct2 are one same reference.  System.out.println("ct1: " + ct1);  System.out.println("ct2: " + ct2);  // if ct1 and ct2 point to one same object, then ct1.myLong == ct2.myLong.  System.out.println("ct1.myLong: " + ct1.myLong);  System.out.println("ct2.myLong: " + ct2.myLong);  // we change ct2's myLong  ct2.myLong = 2L;  // to see whether ct1's myLong was changed.  System.out.println("ct1.myLong: " + ct1.myLong);  System.out.println("ct2.myLong: " + ct2.myLong); }}

Ausgabe:
ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@c17164
ct1.myLong: 1
ct2.myLong: 1
ct1.myLong: 2
ct2.myLong : 2
Das ist sehr einfach, jeder, der Java studiert, weiß es wahrscheinlich (sind diejenigen, die es nicht wissen, diejenigen, die Java studieren?).
Im Speicher wird die Referenz des Objekts im Stapel gespeichert, die Daten des Objekts werden im Heap gespeichert und die Referenz im Stapel zeigt auf das Objekt im Heap. Hier sind die Referenzen in den beiden Stapeln, die auf dasselbe Objekt im Heap verweisen. Daher können Sie sehen, dass sich auch der myLong-Wert von ct1 entsprechend ändert. Wenn dies durch ein Diagramm dargestellt wird, ist dies einfach zum Verständnis.:

Ausführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werden

Die linke Seite ist der Stapelbereich mit demselben Wert Objekt im rechten Heap-Bereich.
Meistens verwenden wir diese Funktion der Java-Sprache, um das zu tun, was wir tun möchten. Übergeben Sie beispielsweise einen Verweis auf ein Objekt als Eingabeparameter und nehmen Sie in der Methode entsprechende Änderungen vor auf das Objekt, auf das die Referenz verweist. Aber manchmal möchten wir ein Objekt erstellen, das genau den gleichen Inhalt wie ein vorhandenes Objekt hat, aber auf ein anderes Objekt verweist. Dazu können Sie Folgendes tun:

Der Code lautet wie folgt:

public class DeepCloneTest{ // must implements Cloneable. private class CloneTest implements Cloneable{  private Object o = new Object();  public CloneTest clone() {   CloneTest ct = null;   try {    ct = (CloneTest)super.clone();   } catch (CloneNotSupportedException e) {    e.printStackTrace();   }   return ct;  } } public static void main(String args[]) {  new DeepCloneTest().Test(); } public void Test() {  CloneTest ct1 = new CloneTest();  CloneTest ct2 = ct1.clone();  // to see if ct1 and ct2 are one same reference.  System.out.println("ct1: " + ct1);  System.out.println("ct2: " + ct2);  // whether ct1.o == ct2.o ? yes  System.out.println("ct1.o " + ct1.o);  System.out.println("ct1.o " + ct1.o); }}
Ausgabe:

ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@1fb8ee3
ct1.o java.lang.Object@61de33
ct1.o java.lang.Object@61de33
Wie aus der Ausgabe ersichtlich ist: ct1 und ct2 sind tatsächlich zwei verschiedene Referenzen, daher gehen wir davon aus, dass ct1.o und ct2.o auch zwei verschiedene sind Objekte, aber Sie können der Ausgabe entnehmen, dass dies nicht der Fall ist! ct1.o und ct2.o sind das gleiche Objekt! Der Grund dafür ist, dass das Obige zwar verwendet wird, aber nur ein oberflächlicher Klon ist, der grafisch dargestellt wird:


Ausführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werdenSehen Sie das o oben? Tatsächlich wird es von zwei Objekten gemeinsam genutzt. Dies ist gleichbedeutend damit, dass Sie ursprünglich einen Schafstall 1 mit einem Schaf darin hatten und dann einen Schafstall 2 gebaut haben. Ohne die Schafe aus Schafstall 1 herauszunehmen, haben Sie die Schafe auch darin eingepfercht. In Pferch 2 dachten Sie, Sie hätten es getan zwei Schafe, aber eigentlich? Jeder weiß es.


Dies ist das Ergebnis des flachen Klonens: Wenn Sie möchten, dass zwei Objekte ein unabhängiges o haben, müssen Sie o erneut klonen. Manche Leute denken vielleicht, dass dies nichts ist, tun Sie es einfach, aber haben Sie jemals darüber nachgedacht, ob es mehr als ein o gibt und es viele, viele Dinge gibt, die o ähneln, klonen Sie sie dann einzeln? Offensichtlich ist es unrealistisch.

Eine Lösung ist: Serialisieren und speichern Sie das Objekt zuerst im Stream und lesen Sie dann das Objekt aus dem Stream, damit es ausgelesen werden kann Die Daten und die Werte im vorherigen Objekt sind genau gleich, genau wie bei einer vollständigen Kopie.

Der Code lautet wie folgt:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class DeepCloneTest {
 // must implements Cloneable.
 private class CloneTest implements Serializable{
  private static final long serialVersionUID = 1L;
  private Object o = new Object();
  public CloneTest deepClone() {
   CloneTest ct = null;
   try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
             ObjectOutputStream oos = new ObjectOutputStream(baos); 
             oos.writeObject(this);
             ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
             ObjectInputStream ois= new ObjectInputStream(bais); 
             ct = (CloneTest)ois.readObject(); 
   } catch (IOException e) {
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
   return ct;
  }
 }
 public static void main(String args[]) {
  new DeepCloneTest().Test();
 }
 public void Test() {
  CloneTest ct1 = new CloneTest();
  CloneTest ct2 = ct1.deepClone();
  // to see if ct1 and ct2 are one same reference.
  System.out.println("ct1: " + ct1);
  System.out.println("ct2: " + ct2);
  // whether ct1.o == ct2.o ? no
  System.out.println("ct1.o " + ct1.o);
  System.out.println("ct1.o " + ct1.o);
 }
}

Zu diesem Zeitpunkt sind die Daten im Speicher wie folgt:

Ausführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werden

Die Klonaufgabe ist abgeschlossen.

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung von Beispielen für das Klonen von Objekten, die durch Java-Serialisierungszugriff implementiert werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn