下面這段程式碼中,為什麼
//对引用的对象也进行复制
o.p=(Professor)p.clone();
就能夠實現深拷貝呢?
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);
}
}
巴扎黑2017-05-17 10:09:33
這只是表面上看起來是「深拷貝」, 實際上Student、Professor都沒有實現深拷貝。
你在main方法增加幾個輸出:
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.clone();
System.out.println(s1.p == s2.p); //false
System.out.println(s1.name == s2.name); // true
System.out.println(s1.p.name == s2.p.name); //true
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);
System.out.println(s1.name == s2.name); //true
System.out.println(s1.p.name == s2.p.name); //false
即可看到,s1,s2的name仍然是"==", 在未set p.name時其name也為"==", 所以說都沒有實現深拷貝。
當你set s2.p.name時,s2.p.name指向了另一個字串常數的位址,所以(s1.p.name == s2.p.name); //false
天蓬老师2017-05-17 10:09:33
並不是深拷貝, 你可以試試clone得到的professor.name
与原来的professor.name
是==
的, 說明String還是引用的原來的
淡淡烟草味2017-05-17 10:09:33
jdk clone方法的預設實作都是value copy,對於基本型,就是把copy值。對於引用,就是copy引用所指向的位址。
所以如果沒有o.p=(Professor)p.clone();
這段程式碼,那麼原對象和clone對象的p,引用的都是同一個Professor對象,也就是淺copy。