obj.clone().getClass()==obj.getClass(),即它們具備相同的類型。還有一點,由於只是簡單的將對象的空間進行復 制,因此若是類具備引用類型的實例變量的話,也只是將這個引用進行拷貝,並不複製其引用的對象。這就致使拷貝對象的引用實例變量與原對象的指向相同的對 象,這就是傳說中的「淺拷貝」。若是實例變量引用的對象是不可變的,相似於String,則拷貝對象與原對象不能互相影響,這樣的拷貝是成功的。可是若是 引用的是可變對象,它們就會影響彼此,對於成功的拷貝而言,這是不容許的。能夠對可變的實例變量對象進行特殊處理,以實現拷貝對象和原對象不能相互影響的 「深拷貝」。java
因爲Object.clone()方法是protected的,因此它只能在lang包中的類或是其子類的方法內部被調用,因此,若是像下面這樣調用,會 編譯出錯,在Person kobe_bak=kobe.clone();報錯,說clone只能在Object的protected做用域訪問。
app
一個類能夠被clone,必須知足兩點:
第一,它必須實現了Cloneable接口,不然會拋出CloneNotSupportedException異常。
第二,它必須提供一個public的clone方法,也就是重寫Object.clone()方法,不然編譯不能經過。
第三,對於存在可變域的類,在clone方法中須要對這些可變域進行拷貝。字體
package test.javacopy; import java.util.Date; /** * Created by Administrator on 2016/1/5. */ public class JavaCopy implements Cloneable { private String name; private int age; private Date date; private TestCopy testcopy; public JavaCopy(String name,int age){ this.name = name; this.age = age; } public JavaCopy clone(){ JavaCopy javaCopy = null; try { javaCopy = (JavaCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return javaCopy; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public TestCopy getTestcopy() { return testcopy; } public void setTestcopy(TestCopy testcopy) { this.testcopy = testcopy; } }
package test.javacopy; import java.io.Serializable; import java.util.Date; /** * Created by Administrator on 2016/1/5. */ public class TestCopy implements Serializable,Cloneable{ private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public TestCopy clone(){ TestCopy testCopy = null; try { testCopy = (TestCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return testCopy; } public static void main(String args[]) { TestCopy testcopy = new TestCopy(); testcopy.setName("javaCopy"); JavaCopy javaCopy = new JavaCopy("123", 123); javaCopy.setDate(new Date()); javaCopy.setTestcopy(testcopy); JavaCopy javaCopy1 = javaCopy.clone(); System.out.println("===javaCopy1===" + javaCopy1.getName() + "age" + javaCopy1.getAge() + "date" + javaCopy1.getDate()); javaCopy1.setName("321"); javaCopy1.setAge(321); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } javaCopy.setDate(new Date()); javaCopy.getTestcopy().setName("javaCopy1"); System.out.println("===javaCopy=== name" + javaCopy.getName()); System.out.println("===javaCopy1=== name" + javaCopy1.getName()); System.out.println("===javaCopy=== age" + javaCopy.getAge()); System.out.println("===javaCopy1=== age" + javaCopy1.getAge()); System.out.println("===javaCopy=== date" + javaCopy.getDate()); System.out.println("===javaCopy1=== date" + javaCopy1.getDate()); System.out.println("===javaCopy=== testcopy name" + javaCopy.getTestcopy().getName()); System.out.println("===javaCopy1=== testcopy name" + javaCopy1.getTestcopy().getName()); } }
執行的結果:this
===javaCopy1===123age123dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== name123
===javaCopy1=== name321
===javaCopy=== age123
===javaCopy1=== age321
===javaCopy=== dateTue Jan 05 13:52:11 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy13d
注意添加的粗字體的代碼(深拷貝)
code
public JavaCopy clone(){ JavaCopy javaCopy = null; try { javaCopy = (JavaCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return javaCopy; }
執行結果:對象
===javaCopy=== dateTue Jan 05 13:55:15 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:55:13 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy接口
jdk中的arraylist深拷貝實現:element
public Object clone() { try { ArrayList<E> v = (ArrayList<E>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } }