[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));
}

}

結果:




進階參考網站:

小妖與鴨居的家

 

 















其它文章

arrow
arrow
    文章標籤
    java 物件 複製 clone
    全站熱搜

    PG Levin Li 發表在 痞客邦 留言(0) 人氣()