Maison  >  Article  >  Java  >  Explication détaillée d'exemples de clonage d'objets implémentés par l'accès à la sérialisation Java

Explication détaillée d'exemples de clonage d'objets implémentés par l'accès à la sérialisation Java

Y2J
Y2Joriginal
2017-04-26 10:05:301230parcourir

Cet article est une analyse détaillée et une introduction à la méthode d'accès sérialisé pour réaliser un clonage profond d'objets Java. Les amis qui en ont besoin peuvent s'y référer

Nous savons qu'en Java, un type non prototype. Après avoir attribué la référence d'objet à une autre référence d'objet, les deux références pointent vers le même objet, tel que :

Le code est le suivant :

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); }}

sortie :
ct1 : DeepCloneTest$CloneTest@c17164
ct2 : DeepCloneTest$CloneTest@c17164
ct1.myLong : 1
ct2.myLong : 1
ct1.myLong : 2
ct2.myLong : 2
C'est très simple, tous ceux qui étudient Java le savent probablement (ceux qui ne savent pas sont-ils ceux qui étudient Java ?).
En mémoire, la référence de l'objet est stockée dans la pile, les données de l'objet sont stockées dans le tas et la référence dans la pile pointe vers l'objet dans le tas. Voici les références dans les deux piles, pointant vers le même objet dans le tas. Par conséquent, lorsque le myLong de ct2 est modifié, vous pouvez voir que la valeur myLong de ct1 change également si elle est représentée par un diagramme. comprendre.:

Explication détaillée d'exemples de clonage d'objets implémentés par l'accès à la sérialisation Java

Le côté gauche est la zone de pile. Il y a deux références dans cette zone avec la même valeur. dans la zone de tas de droite.
La plupart du temps, nous utiliserons cette fonctionnalité du langage Java pour faire ce que nous voulons faire. Par exemple, passer la référence de l'objet comme paramètre d'entrée dans une méthode, et dans la méthode, apporter les modifications correspondantes. objet pointé par la référence. Mais parfois, nous voulons construire un objet qui a exactement le même contenu qu'un objet existant mais référence un objet différent. Pour ce faire, peut faire ceci  :

Le code. est la suivante :

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); }}

sortie :
ct1 : DeepCloneTest$CloneTest@c17164
ct2 : DeepCloneTest$CloneTest@1fb8ee3
ct1.o java.lang.Object@61de33
ct1. o java.lang.Object@61de33
Comme le montre le résultat : ct1 et ct2 sont en effet deux références différentes, nous tenons donc pour acquis que ct1.o et ct2.o sont également deux références différentes. objets, mais vous pouvez voir sur la sortie que ce n'est pas le cas ! ct1.o et ct2.o sont le même objet ! La raison en est que bien que le clonage soit utilisé, ce qui précède n'est qu'un clone superficiel, représenté graphiquement :

Explication détaillée d'exemples de clonage d'objets implémentés par l'accès à la sérialisation Java
Voir le o ci-dessus ? En fait, il est partagé par deux objets. Cela équivaut à, à l'origine, vous aviez une bergerie 1 avec un mouton dedans, puis vous avez créé une bergerie 2. Sans sortir le mouton de la bergerie 1, vous avez également parqué le mouton dans l'enclos 2, vous pensiez l'avoir. deux moutons, mais au fait ? Tout le monde le sait.

C'est le résultat d'un clonage superficiel : Si vous voulez que deux objets aient un o indépendant, vous devez cloner à nouveau o. Certaines personnes peuvent penser que ce n'est rien, faites-le, mais y avez-vous déjà pensé, s'il y a plus d'un o, et qu'il y a beaucoup, beaucoup de choses similaires à o, les clonez-vous un par un ? C'est évidemment irréaliste.

Une solution est : Sérialisez et stockez d'abord l'objet dans le flux, puis lisez l'objet à partir du flux, afin qu'il puisse être lu. Les données et les valeurs de l'objet précédent sont exactement les mêmes, tout comme une copie complète.

Le code est le suivant :

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);
 }
}


A ce moment, les données en mémoire sont comme ceci :

Explication détaillée d'exemples de clonage d'objets implémentés par l'accès à la sérialisation Java

La tâche de clonage est terminée.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn