Java克隆Clone

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

你可能感兴趣的:(Java克隆Clone)