http://www.blogjava.net/woxingwosu/archive/2008/01

Java克隆Clone
☆什么是Clone Clone就是得到一个对象x的副本,而且x.clone() != x。Clone分为两种:浅度克隆Shallow Clone和浅度克隆Deep Clone


Object类有clone()方法: protected native Object clone() throws CloneNotSupportedException; 但是Object本身没有implements Cloneable,在执行clone方法时,先检查this.getClass()是否实现了cloneable接口,如果没有实现Cloneable接口,clone()就会抛CloneNotSupportedException返回。否则就会创建一个新的this.getClass()的对象other,并将this每一个field的值赋值给other的对应field,然后返回other。

接口Cloneable起一个标志作用(和Serializable类似),用来标志该类具有克隆功能。


☆实现Shallow clone Shallow Clone只是将基本类型赋值过去,对于对象传的是引用。(String对于比较特别,[一般内容一样则引用一样,轻量级模式])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;
}
}输出结果
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;
}
}输出结果
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之间的修改相互影响,这时就应该用深度克隆。对所有涉及到的对象也实现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;
}
}输出结果
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.blogjava.net/orangelizq/archive/2007/10/17/153573.html
http://www.blogjava.net/junky/archive/2007/05/08/115928.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值