[JAVA]Object-物件的複製使用clone()
要使用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));
}
}
結果:
進階參考網站:
其它文章