?? 有的時候我們為了獲取對象的一份copy,可以利用Object類的clone方法來實現,要想實現克隆,我們必須在派生類中實現Cloneable interface并覆蓋基類的clone()方法,并擴大訪問權限為public,在派生類的clone()方法,調用super.clone()。
?demo:
class StringTest
{
?public static void main(String[] args)
?{
??Professior p = new Professior("wangwu",50);
??Student s1 = new Student("zhangsan",18,p);
??Student s2 = (Student)s1.clone();
??s2.p.name = "lisi";
??s2.p.age = 20;
??
??System.out.println("s1.p.name="+s1.p.name+","+"s1.p.age="+s1.p.age);
?}
}
class Student implements Cloneable
{
? Professior p;
? String name;
? int age;
?
?public Student(String name,int age,Professior p)
?{
??this.name =name;
??this.age = age;
??this.p = p;
?}
?
?public Object clone()
?{
??Object o = null;
??try
??{
???o=super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??return o;
?}
?
?public String toString()
?{
??return "name="+name+","+"age="+age;
?}
}
class Professior
{
?String name;
?int age;
?public Professior(String name,int age)
?{
??this.name = name;
??this.age = age;
?}
}
Result:
D:\jcode>java StringTest
s1.p.name=lisi,s1.p.age=20
通過結果看得出一個問題,當我們修改s2的Professior后,s1對象的Professior對象的值被修改了。不是有clone了2份copy嗎?那怎么修改S1的值卻影響了S2的值了,那是因為我們克隆的時候只是把Professior的引用復制了一份,而并沒有實際在內存中給它分配到一塊內存,所以我們clone的時候,其實是把同一個值給復制了2次,所以s1和s2操作的professior都是同一個對象,所以修改S1,必然就影響了S2的professior的值,那我們的本意并非如此,有沒有辦法解決呢?答案是肯定的。其實我們剛才所做的操作是一個淺克隆,當我們克隆的對象是引用類型的時候,可以用深克隆來實現。就如下面的Demo.
class CloneTest
{
?public static void main(String[] args)
?{
??Boss boss = new Boss("antsoul",25);
??Leader leader = new Leader("linda",30);
??Employee ep1 = new Employee("zhangsan",107,leader,boss);
??? Employee ep2 = (Employee)ep1.clone();
??? ep2.boss.name = "gll";
??? ep2.boss.age = 60;
??? System.out.println("ep1.leader.name="+ep1.boss.name);
??? System.out.println("ep1.leader.age="+ep1.boss.age);
?}?
}
class Employee implements Cloneable
{
?String name;
?int eid;
?Leader leader;
?Boss boss;
?
?Employee(String name,int eid,Leader leader,Boss boss)
?{
??this.name = name;
??this.eid = eid;
??this.leader = leader;
??this.boss = boss;
?}
?
?public Object clone()
?{
??Employee o = null;
??try
??{
???o = (Employee)super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??o.leader = (Leader)leader.clone();
??o.boss = (Boss)boss.clone();
??return o;
?}
}
class Leader implements Cloneable
{
?String name;
?int age;
?
?Leader(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;
?}
}
class Boss implements Cloneable
{
?String name;
?int age;
?
?Boss(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.getMessage());
??}
??return o;
?}
}
這里有個疑問了,為什么我們要在派生類中over writte Object的clone()方法時,一定要調用super.clone()呢?
原因是: 在運行時刻,Object中的clone()識別出你要clone的是哪一個對象,然后為此對象分配內存空間,并進行對象的復制,將原始對象的內容一一復制到新的對象空間中去。