☆
什么是Clone
Clone就是得到一個對象x的副本,而且x.clone() != x。Clone分為兩種:淺度克隆Shallow Clone和淺度克隆Deep Clone
Object類有clone()方法: protected native Object clone() throws CloneNotSupportedException; 但是Object本身沒有implements Cloneable,在執(zhí)行clone方法時,先檢查this.getClass()是否實現(xiàn)了cloneable接口,如果沒有實現(xiàn)Cloneable接口,clone()就會拋CloneNotSupportedException返回。否則就會創(chuàng)建一個新的this.getClass()的對象other,并將this每一個field的值賦值給other的對應field,然后返回other。
接口Cloneable起一個標志作用(和Serializable類似),用來標志該類具有克隆功能。
☆
實現(xiàn)Shallow clone
Shallow Clone只是將基本類型賦值過去,對于對象傳的是引用。(String對于比較特別,[一般內(nèi)容一樣則引用一樣,輕量級模式])

Shallow Clone
public class Test {
public static void main(String[] args) throws Exception{
Area area=new Area("fujian");
System.out.println("area:"+area);
Area areaClone=area.clone();
System.out.println("areaClone:"+areaClone);
System.out.println("area==areaClone:"+(area==areaClone));
System.out.println("area.getClass()==areaClone.getClass():"+(area.getClass()==areaClone.getClass()));
area.province="jiangxi";
System.out.println("area:"+area);
System.out.println("areaClone:"+areaClone);
}
}
class Area implements Cloneable{
String province;
Area(String province){
this.province=province;
}
@Override
public Area clone(){
Area area=null;
try{
area=(Area)super.clone();
}catch(CloneNotSupportedException cnse){
cnse.printStackTrace();
}
return area;
}
@Override
public String toString(){
return "\tprovince="+province;
}
}

輸出結(jié)果
area: province=fujian
areaClone: province=fujian
area==areaClone:false
area.getClass()==areaClone.getClass():true
area: province=jiangxi
areaClone: province=fujian
☆
Shallow Clone的問題
因為對于對象只是拷貝引用,所有就會造成this對其中對象的修改引起other中相應對象的修改,例子如下:

Shallow Clone問題
public class Test {
public static void main(String[] args) throws Exception{
Area area=new Area("fujian","fujian info");
Area areaClone=area.clone();
System.out.println("area:"+area);
System.out.println("areaClone:"+areaClone);
area.province="jiangxi";
area.info.name="new info";
System.out.println("--------After Change-------");
System.out.println("area:"+area);
System.out.println("areaClone:"+areaClone);
}
}
class Area implements Cloneable{
String province;
Info info;
Area(String province,String infoName){
this.province=province;
info=new Info(infoName);
}
@Override
public Area clone(){
Area area=null;
try{
area=(Area)super.clone();
}catch(CloneNotSupportedException cnse){
cnse.printStackTrace();
}
return area;
}
@Override
public String toString(){
return "\tprovince="+province+"\t info="+info.name;
}
}
class Info{
String name;
Info(String name){
this.name=name;
}
}

輸出結(jié)果
area: province=fujian info=fujian info
areaClone: province=fujian info=fujian info
--------After Change-------
area: province=jiangxi info=new info
areaClone: province=fujian info=new info
☆
Deep Clone
有些時候我們不希望this與other之間的修改相互影響,這時就應該用深度克隆。對所有涉及到的對象也實現(xiàn)Clone。

Deep Clone
public class Test {
public static void main(String[] args) throws Exception{
Area area=new Area("fujian","fujian info");
Area areaClone=area.clone();
System.out.println("area:"+area);
System.out.println("areaClone:"+areaClone);
area.province="jiangxi";
area.info.name="new info";
System.out.println("--------After Change-------");
System.out.println("area:"+area);
System.out.println("areaClone:"+areaClone);
}
}
class Area implements Cloneable{
String province;
Info info;
Area(String province,String infoName){
this.province=province;
info=new Info(infoName);
}
@Override
public Area clone(){
Area area=null;
try{
area=(Area)super.clone();
area.info=this.info.clone();
}catch(CloneNotSupportedException cnse){
cnse.printStackTrace();
}
return area;
}
@Override
public String toString(){
return "\tprovince="+province+"\t info="+info.name;
}
}
class Info implements Cloneable{
String name;
Info(String name){
this.name=name;
}
@Override
public Info clone(){
Info info=null;
try{
info=(Info)super.clone();
}catch(CloneNotSupportedException cnse){
cnse.printStackTrace();
}
return info;
}
}

輸出結(jié)果
area: province=fujian info=fujian info
areaClone: province=fujian info=fujian info
--------After Change-------
area: province=jiangxi info=new info
areaClone: province=fujian info=fujian info
☆
參考:
http://www.tkk7.com/orangelizq/archive/2007/10/17/153573.html
http://www.tkk7.com/junky/archive/2007/05/08/115928.html
posted on 2008-01-30 16:41
破繭而出 閱讀(709)
評論(0) 編輯 收藏 所屬分類:
Java