下面這段程式碼中,為什麼
//对引用的对象也进行复制
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);
}
}
這只是表面上看起來是「深拷貝」, 實際上Student、Professor都沒有實現深拷貝。
你在main方法增加幾個輸出:
即可看到,s1,s2的name仍然是"==", 在未set p.name時其name也為"==", 所以說都沒有實現深拷貝。
當你set s2.p.name時,s2.p.name指向了另一個字串常數的位址,所以(s1.p.name == s2.p.name); //false
你這個是淺複製,只能複製基本的資料類型,要複製物件成員變量,還需要呼叫該成員變數的clone方法,我是這麼理解的,多次淺複製實現深複製
並不是深拷貝, 你可以試試clone得到的
professor.name
与原来的professor.name
是==
的, 說明String還是引用的原來的jdk clone方法的預設實作都是value copy,對於基本型,就是把copy值。對於引用,就是copy引用所指向的位址。
所以如果沒有
o.p=(Professor)p.clone();
這段程式碼,那麼原對象和clone對象的p,引用的都是同一個Professor對象,也就是淺copy。