1 et 1 Copie peu profonde et concept de copie profonde
Copie de SHALLOW (clonage peu profond)
Toutes les variables de l'objet copié contiennent la même valeur que l'objet d'origine, tandis que toutes les références à d'autres objets pointent toujours vers l'objet d'origine. En d'autres termes, la copie superficielle copie simplement l'objet considéré, et non l'objet qu'il fait référence.
⑵ Copie profonde (clonage profond)
Toutes les variables de l'objet copié contiennent la même valeur que l'objet d'origine, à l'exception des variables qui se réfèrent à d'autres objets. Les variables qui se réfèrent à d'autres objets pointeront vers le nouvel objet copié, au lieu des objets référencés d'origine. En d'autres termes, une copie profonde copie tous les objets référencés par l'objet à copier.
2 Méthode Clone () de Java
⑴ La méthode du clone copie une copie de l'objet et la renvoie à l'appelant. D'une manière générale, la méthode clone () satisfait:
① Pour tout objet x, il y a x.clone ()! = X // L'objet cloné n'est pas le même objet que l'objet d'origine ② pour tout objet x, il y a x.clone (). GetClass () = = x .
⑵Clone des objets en Java
① Afin d'obtenir une copie de l'objet, nous pouvons utiliser la méthode Clone () de la classe d'objet.
② Écraser la méthode clone () de la classe de base dans la classe dérivée et le déclarer comme public.
③ Dans la méthode clone () de la classe dérivée, appelez super.clone ().
④ Implémentez l'interface clonable dans la classe dérivée.
Veuillez consulter le code suivant:
classe publique implémente Cloneable {Nom de la chaîne; Student) super.clone (); // clone () dans l'objet reconnaît l'objet que vous souhaitez copier. } catch (clonenotsupportEdException e) {System.out.println (e.toString ()); S2 = (Student) S1.Clone (); S2.Name = "Lisi"; S2.age = 20; System.out.println ("name =" + s1.name + "," + "age =" + s1.age); + s2.age);} illustrer:
①Pour pourquoi devons-nous appeler super.clone () lors de l'écrasement de la méthode clone () de l'objet dans la classe dérivée? Au moment d'exécution, Clone () dans l'objet reconnaît l'objet que vous souhaitez copier, puis alloue l'espace à cet objet et copie l'objet, en copie le contenu de l'objet d'origine un par un dans l'espace de stockage du nouvel objet.
② La méthode clone () héritée de la classe java.lang.object est une copie superficielle. Le code suivant peut le prouver.
Classe Professeur {Nom de la chaîne; Int Age; Âge; Étudiant (nom de la chaîne, Âge, professeur P) {this.name = name; .Clone ();} Catch (clonenotsupporTedException e) {System.out.println (e.toString ());} op = (professeur) p.clone (); ) {Professeur P = nouveau professeur ("Wangwu", 50); Student S1 = New Student ("Zhangsan", 18, P); "; s2.p.age = 30; System.out.println (" name = "+ s1.p.name +", "+" age = "+ s1.p.age); System.out.println (" name = "+ s2.p.name +", "+" Age = "+ S2.p.age); // Les résultats de sortie des professeurs d'étudiants 1 et 2 deviennent Lisi, et l'âge est de 30 ans. }} Alors, comment devrions-nous mettre en œuvre un clonage profond, c'est-à-dire que le professeur qui modifie S2 n'affectera pas le professeur qui S1? Le code est amélioré comme suit.
Améliorations pour faire inchangé le professeur de l'étudiant 1 (clone Deep)
Classe Professeur implémente Cloneable {String Name; Int Age; Clone ();} catch (clonenotsupportEdException e) {System.out.println (e.toString ()); int, professeur p) {this.name = name; } catch (clonenotsupportEdException e) {System.out.println (e.toString ());} // copier l'objet référencé OP = (professeur) p.clone (); ] Args) {Professeur P = nouveau professeur (Wangwu ", 50); étudiant S1 = nouveau étudiant (Zhangsan", 18, P); "Lisi"; S2.p.age = 30; // Le professeur d'étudiant 1 ne changera pas. System.out.println ("name =" + s1.p.name + "," + "age =" + s1.p.age); "+" age = "+ s2.p.age);}} 3 et 3利用串行化来做深复制(主要是为了避免重写比较复杂对象的深复制的clone()方法,也可以程序实现断点续传等等功能)
Le processus d'écriture d'objets dans les flux est un processus de sérialisation, mais il est très vivement appelé le processus "Frozen" ou "Picking" dans les cercles des programmeurs Java; processus.
Il convient de souligner que ce qui est écrit dans le flux est une copie de l'objet, et l'objet d'origine existe toujours dans le JVM, donc ce qui est "Pickled in Pickles" n'est qu'une copie de l'objet, et les cornichons Java peuvent toujours être frais.
La copie profondément d'un objet en langue java peut souvent faire en sorte que l'objet implémente d'abord l'interface sérialisable, puis d'écrire l'objet (en fait juste une copie de l'objet) dans un flux (mariné dans les cornichons), puis de le lire à partir du flux (put Les cornichons en arrière) peuvent reconstruire l'objet.
Ce qui suit est le code source de copie profonde.
Objet public DeepClone () {// Écrivez l'objet dans le flux ByTearRayOutStream Bo = new ByTearRayoutputStream (); Bo.ToByTeArray ()); ObjectInputStream Oi = New ObjectInputStream (BI); La prémisse de le faire est que l'objet et tous les objets référencés dans l'objet sont sérialisables. . dehors. L'exemple de code ci-dessus est amélioré comme suit.
Le professeur de classe implémente Serializable {Nom de la chaîne; Âge; enseignant T; // Les valeurs de référence de l'élève 1 et de l'élève 2 sont les mêmes. Étudiant public Void (nom de la chaîne, Age, professeur T) {this.name = name; Allez dans le flux ByteArrayoutStream bo = new ByteArrayoutputStream (); Nouveau objetInputStream (BI); 18, t); Student S2 = (Student) S1.Deplone (); S2.T.Name = "Tony"; name = "+ s1.t.name +", "+" age = "+ s1.t.age);}}