克隆的步驟:java
1. Object的clone()源代碼簡介數組
/** * Creates and returns a copy of this {@code Object}. The default * implementation returns a so-called "shallow" copy: It creates a new * instance of the same class and then copies the field values (including * object references) from this instance to the new instance. A "deep" copy, * in contrast, would also recursively clone nested objects. A subclass that * needs to implement this kind of cloning should call {@code super.clone()} * to create the new instance and then create deep copies of the nested, * mutable objects. * * @return a copy of this object. * @throws CloneNotSupportedException * if this object's class does not implement the {@code * Cloneable} interface. */ protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class doesn't implement Cloneable"); } return internalClone((Cloneable) this); } /* * Native helper method for cloning. */ private native Object internalClone(Cloneable o);
clone方法首先會判對象是否實現了Cloneable接口,若無則拋出CloneNotSupportedException, 最後會調用internalClone. intervalClone是一個native方法,通常來講native方法的執行效率高於非native方法。ide
當某個類要複寫clone方法時,要繼承Cloneable接口。一般的克隆對象都是經過super.clone()方法來克隆對象。this
2.淺克隆(shadow clone).net
克隆就是複製一個對象的複本.若只須要複製對象的字段值(對於基本數據類型,如:int,long,float等,則複製值;對於複合數據類型僅複製該字段值,如數組變量則複製地址,對於對象變量則複製對象的reference。code
package haust.vk.demo; public class ShadowClone implements Cloneable{ private int a; // 基本類型 private int[] b; // 非基本類型 // 重寫Object.clone()方法,並把protected改成public @Override public Object clone(){ ShadowClone sc = null; try { sc = (ShadowClone) super.clone(); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return sc; } public int getA() { return a; } public void setA(int a) { this.a = a; } public int[] getB() { return b; } public void setB(int[] b) { this.b = b; } }
package haust.vk.demo; public class App { public static void main(String[] args) throws CloneNotSupportedException{ ShadowClone c1 = new ShadowClone(); //對c1賦值 c1.setA(100) ; c1.setB(new int[]{1000}) ; System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]); //克隆出對象c2,並對c2的屬性A,B,C進行修改 ShadowClone c2 = (ShadowClone) c1.clone(); System.out.println("克隆後c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); //對c2進行修改 c2.setA(50) ; int []a = c2.getB() ; a[0]=5 ; c2.setB(a); System.out.println("修改後c1: a="+c1.getA()+" b="+c1.getB()[0]); System.out.println("修改後c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); } }
基本類型能夠使用淺克隆,而對於引用類型,因爲引用的是內容相同,因此改變c2實例對象中的屬性就會影響。對象
深克隆(deep clone)繼承
深克隆與淺克隆的區別在於對複合數據類型的複製。若對象中的某個字段爲複合類型,在克隆對象的時候,須要爲該字段從新建立一個對象。接口
public class DeepClone implements Cloneable { private int a; // 基本類型 private int[] b; // 非基本類型 // 重寫Object.clone()方法,並把protected改成public @Override public Object clone(){ DeepClone sc = null; try { sc = (DeepClone) super.clone(); int[] t = sc.getB(); int[] b1 = new int[t.length]; for (int i = 0; i < b1.length; i++) { b1[i] = t[i]; } sc.setB(b1); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return sc; } public int getA() { return a; } public void setA(int a) { this.a = a; } public int[] getB() { return b; } public void setB(int[] b) { this.b = b; } }
package haust.vk.demo; public class AppDeep { public static void main(String[] args) throws CloneNotSupportedException{ DeepClone c1 = new DeepClone(); //對c1賦值 c1.setA(100) ; c1.setB(new int[]{1000}) ; System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]); //克隆出對象c2,並對c2的屬性A,B,C進行修改 DeepClone c2 = (DeepClone) c1.clone(); System.out.println("克隆後c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); //對c2進行修改 c2.setA(50) ; int []a = c2.getB() ; a[0]=5 ; c2.setB(a); //基本類型能夠使用淺克隆,而對於引用類型,因爲引用的是內容相同,因此改變c2實例對象中的屬性就會影響到c1 System.out.println("修改後c1: a="+c1.getA()+" b="+c1.getB()[0]); System.out.println("修改後c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); } }
代碼:get
下載地址: http://download.csdn.net/detail/meryhuang/9695751