Dans le code ci-dessous, pourquoi
//对引用的对象也进行复制
o.p=(Professor)p.clone();
Est-il possible de réaliser une copie approfondie ?
class Professor implements Cloneable
{
String name;
int age;
Professor(String name,int age)
{
this.name=name;
this.age=age;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}
public class Student implements Cloneable
{
String name;
int age;
Professor p;
Student(String name,int age,Professor p)
{
this.name=name;
this.age=age;
this.p=p;
}
public Object clone()
{
Student o=null;
try
{
o=(Student)super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
//对引用的对象也进行复制
o.p=(Professor)p.clone();
return o;
}
public static void main(String[] args)
{
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.clone();
s2.p.name="lisi";
s2.p.age=30;
//学生1的教授不 改变。
System.out.println("name="+s1.p.name+","+"age="+s1.p.age);
System.out.println("name="+s2.p.name+","+"age="+s2.p.age);
}
}
Cela semble être une "copie profonde" en surface En fait, ni l'étudiant ni le professeur n'implémentent la copie profonde.
Vous ajoutez plusieurs sorties à la méthode main :
Vous pouvez voir que les noms de s1 et s2 sont toujours "==" Lorsque p.name n'est pas défini, leurs noms sont également "==", donc aucune copie profonde n'est implémentée.
);Lorsque vous définissez s2.p.name, s2.p.name pointe vers l'adresse d'une autre constante de chaîne, donc (s1.p.name == s2.p.name //false
Il s'agit d'une copie superficielle, qui ne peut copier que les types de données de base. Pour copier une variable membre d'un objet, vous devez appeler la méthode de clonage de la variable membre. C'est ainsi que je comprends que plusieurs copies superficielles peuvent obtenir une copie approfondie.
Ce n'est pas une copie complète. Vous pouvez essayer de la cloner. Cela signifie que la chaîne est toujours référencée à l'originale
professor.name
与原来的professor.name
是==
.L'implémentation par défaut de la méthode de clonage jdk est la copie de valeur. Pour les types de base, la valeur de copie est utilisée. Pour les références, il s'agit de l'adresse pointée par la référence de copie.
Donc, s'il n'y a pas de
o.p=(Professor)p.clone();
ce code, alors le p de l'objet original et l'objet clone font référence au même objet Professeur, qui est une copie superficielle.