克隆的步骤: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