(Explication : Cet article porte sur la différence et la méthode de mise en œuvre entre le clonage profond et le clonage superficiel ?)
Parler ne coûte pas cher#
J'ai rencontré du clonage profond et superficiel (copie profonde, copie superficielle) plus de une fois récemment. Question, à part l'impression qu'il existe une méthode de clonage, je suis confus ! ! ! Le clonage (copie) est une opération courante en Java pour obtenir rapidement une copie d'un objet. Le clonage est divisé en clonage profond et clonage superficiel.
Clonage superficiel : Créez un nouvel objet. Les propriétés du nouvel objet sont exactement les mêmes que celles de l'objet d'origine. Pour les propriétés de type non basiques, elles pointent toujours vers l'adresse mémoire de l'objet pointé. par les propriétés originales.
Clonage profond : créez un nouvel objet, et les autres objets référencés dans les attributs seront également clonés et ne pointeront plus vers l'adresse de l'objet d'origine.
En bref, le clonage profond et superficiel allouera une nouvelle zone dans le tas. La différence réside dans le fait que l'objet référencé par l'attribut object doit être cloné (de manière récursive).
Montrer ma photo#
pos : l'adresse de l'objet actuel ;
fils : l'adresse pointée par l'attribut fils
nom ; : le nom de la propriété de l'objet.
(Recommandations associées :Tutoriel d'introduction à Java
)Montrez-vous mon code#case1 :
public class Son implements Serializable , Cloneable{ private String name; private Son son; public Son() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Son getSon() { return son; } public void setSon(Son son) { this.son = son; } @Override public String toString() { return super.toString(); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
Testpublic static void main(String[] args) throws Exception{ // 创建父亲(LiLiu),儿子(LiWu),孙子(LiLiu)并关联
Son father = new Son();
father.setName("LiSi");
Son son = new Son();
son.setName("LiWu");
Son grandSon = new Son();
grandSon.setName("LiLiu");
father.setSon(son);
son.setSon(grandSon); // 调用clone方法
Son fatherCopy = (Son) father.clone(); boolean flag1 = fatherCopy==father; boolean flag2 = fatherCopy.getSon() == son; boolean flag3 = fatherCopy.getSon().getSon() == grandSon; // 比较克隆后的地址
System.out.println(flag1);// false
System.out.println(flag2);// true
System.out.println(flag3);// true
// 比较Name
flag1= fatherCopy.getName()==father.getName();
flag2 = fatherCopy.getSon().getName() == son.getName();
flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
System.out.println(flag1);// true
System.out.println(flag2);// true
System.out.println(flag3);// true
//将对象写到流里
ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
ObjectOutputStream objOut=new ObjectOutputStream(byteOut);
objOut.writeObject(father); //从流里读出来
ByteArrayInputStream byteIn=new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream objInput=new ObjectInputStream(byteIn);
fatherCopy = (Son) objInput.readObject();
flag1= fatherCopy==father;
flag2 = fatherCopy.getSon() == son;
flag3 = fatherCopy.getSon().getSon() == grandSon;
System.out.println(flag1);// false
System.out.println(flag2);// false
System.out.println(flag3);// false
// 比较Name
flag1= fatherCopy.getName()==father.getName();
flag2 = fatherCopy.getSon().getName() == son.getName();
flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
System.out.println(flag1);// false
System.out.println(flag2);// false
System.out.println(flag3);// false}
Réflexion : Depuis l'implémentation de l'interface Cloneable et la réécriture de l'interface de clonage, on ne peut effectuer qu'un clonage superficiel. Cependant, si les attributs de type référence de la classe (et les attributs de type référence de l'attribut) sont clonés superficiellement, jusqu'à ce qu'il n'y ait pas d'attribut de type référence ou que l'attribut de type référence soit nul, un clone profond sera formé dans son ensemble. L'attribut de type de référence de l'objet et l'attribut de type d'application de l'attribut implémentent Coloneable, remplacent la méthode clone et l'appellent dans la méthode clone.
protected Object clone() throws CloneNotSupportedException { Son result = (Son) super.clone(); if (son != null) { result.son = (Son) son.clone(); } return result; }
Personnellement, je pense que lors du choix de la méthode de clonage profond, elle doit être basée sur la complexité de l'objet, par exemple si l'attribut de type de référence a plusieurs couches de relations d'attributs de type de référence. Si l'objet n'a qu'une ou deux couches d'attributs de type référence, il est plus pratique de choisir la méthode mentionnée dans la réflexion. Sinon, utilisez le flux d'objet.
Pour plus de questions d'entretien connexes, veuillez visiter :
questions et réponses d'entretien JavaCe 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!