要使用clone(),需要實作介面Cloneable。
Object 類別本身不實作介面 Cloneable,所以在類別為 Object 的物件上調用 clone 方法將會導致在運行時拋出異常。
CloneNotSupportedException
- 如果物件的類別不支持
Cloneable
介面,則覆寫 clone
方法的子類別也會拋出此異常,以指示無法複製某個實例。
Object 類別的 clone 方法執行特定的複製操作。
首先,如果此物件的類別不能實作介面 Cloneable,
則會拋出 CloneNotSupportedException。
注意,所有的陣列都被視為實作介面 Cloneable。
否則,此方法會創建此物件的類別的一個新實例,並像通過分派那樣,
嚴格使用此物件相應欄位的內容初始化該物件的所有欄位;
這些欄位的內容沒有被自我複製。
所以,此方法執行的是該物件的「淺表複製」,而不「深層複製」操作。
測試:
一般用法:(淺表複製)
package com.test; public class TestClone implements Cloneable { public static final int i=1; @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) { try { TestClone t = new TestClone(); //使用clone TestClone t1 = (TestClone) t.clone(); //顯示記憶體位置 System.out.println(t); //com.test.TestClone@150bd4d System.out.println(t1); //com.test.TestClone@1bc4459 //位置是不一樣了,是不同的物件 //陣列會自動implements Cloneable //所以會有clone的功能 int i[] = {1,2,5,8,8,8}; int a[]=i.clone(); System.out.println(i.equals(a)); //false System.out.println(a[2]); //5 } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
進階用法:( 深層複製 )
例:
用一般的用法:
package com.test; import java.util.ArrayList; public class TestCloneAdvanced implements Cloneable{ private int i; private ArrayList arrayList; @Override public String toString() { return "i=" + i + ",arrayList=" + arrayList; } public static void main(String[] args) { TestCloneAdvanced clone1 = new TestCloneAdvanced(); clone1.i = 3; clone1.arrayList = new ArrayList(); clone1.arrayList.add("value 1"); TestCloneAdvanced clone2 = null; try { clone2 = (TestCloneAdvanced) clone1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } System.out.println("複製物件後,顯示結果:"); System.out.println("clone1:" + clone1); System.out.println("clone2:" + clone2); System.out.println("將clone1改變值後,顯示結果:"); clone1.i = 5; clone1.arrayList.add("value 2"); System.out.println("clone1:" + clone1); System.out.println("clone2:" + clone2); System.out.println("將clone1改變值後,clone2的arrayList的值也會改"); System.out.println("因為arrayList物件沒有複製"); System.out.println("clone1.arrayList==clone2.arrayList?" + (clone1.arrayList == clone2.arrayList)); } }
結果在物件裡的物件,無法複製。
結決方法:Override clone
例:
package com.test; import java.util.ArrayList; public class TestCloneAdvanced1 implements Cloneable { private int i; private ArrayList arrayList; @Override public String toString() { return "i=" + i + ",arrayList=" + arrayList; } @Override public Object clone() throws CloneNotSupportedException { TestCloneAdvanced1 clone = (TestCloneAdvanced1) super.clone(); clone.arrayList = (ArrayList) this.arrayList.clone(); return clone; } public static void main(String[] args) { TestCloneAdvanced1 clone1 = new TestCloneAdvanced1(); clone1.i = 3; clone1.arrayList = new ArrayList(); clone1.arrayList.add("value 1"); TestCloneAdvanced1 clone2 = null; try { clone2 = (TestCloneAdvanced1) clone1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } System.out.println("複製物件後,顯示結果:"); System.out.println("clone1:" + clone1); System.out.println("clone2:" + clone2); System.out.println("將clone1改變值後,顯示結果:"); clone1.i = 5; clone1.arrayList.add("value 2"); System.out.println("clone1:" + clone1); System.out.println("clone2:" + clone2); System.out.println("將clone1改變值後,clone2的arrayList的值不會改了"); System.out.println("clone1.arrayList==clone2.arrayList?" + (clone1.arrayList == clone2.arrayList)); } }結果:
進階參考網站:
小妖與鴨居的家
其它文章
沒有留言:
張貼留言