『壹』 java中深克隆與淺克隆的區別
深克隆與淺克隆
大家知道,對象是互相引用的,即對象中可能包含了另一個對象的引用,舉例如:有一個Order對象,Order對象中又包含了LineItems對象,然後LineItems對象又包含了Item對象。
好了,現在我有一個Order對象order1,它包含了一個LineItems對象items,這表示的是有一個訂單order1,訂單的內容是items。
好的,現在有另一個客戶想要一份訂單,內容跟order1完全一樣,那麼在系統的邏輯層我們怎麼做呢?很簡單,order2=order1.clone().我們知道clone方法是在內存中生成一個新的對象,而不是只得到原對象的引用。這時候,有人說話了:「哦,明白了我們對order2的成員變數進行修改,是不會影響order1的。」很可惜,這句話只對了一半。
假設order類有一個成員變數name,當然改變order2.name不會影響order1.name,因為他們在不同的內存區域。但是如果改變order1.items呢?很遺憾,簡單地使用order1.clone,是會影響到order2.items的。原因很簡單,就是因為clone方法默認的是淺克隆,即不會克隆對象引用的對象,而只是簡單地復制這個引用。所以在上例中,items對象在內存中只有一個,order1和order2都指向它,任何一個對象對它的修改都會影響另一個對象。
那相對淺克隆,深克隆自然就是會克隆對象引用的對象了。也就是說,在上例中,改變order1.items並不會影響order2.items了。因為內存中有兩個一樣的items。
如果實現深克隆?
一個方法自然是重寫clone方法,添加如order.items=(LineItems)items.clone()的語句,也就是人為地添加對引用對象的復制。這個方法的缺點是如果引用對象有很多,或者說引用套引用很多重,那麼太麻煩了。業界常用的方法是使用串列化然後反串列化的方法來實現深克隆。由於串列化後,對象寫到流中,所有引用的對象都包含進來了,所以反串列化後,對等於生成了一個完全克隆的對象。絕!
這個方法的要求是對象(包括被引用對象)必須事先了Serializable介面,否則就要用transient關鍵字將其排除在復制過程中。
『貳』 如何克隆Java對象
Java中的對象涉及使用引用類型,沒有直接的方法可將一個對象的內容復制到一個新對象中。將一個引用分配給另一個引用只會給相同對象建立另一個引用。因此,Java對所有引用類型使用一個特殊的clone()方法,為對象復制自身提供一個標準的機制。以下是你需要了解和克隆Java對象有關的細節。為何建立一個本地拷貝?給一個對象建立本地拷貝的原因很可能是由於你計劃修改該對象,並且你不想修改方法調用者的對象。如果你確定你需要一個本地拷貝,你可以使用Object類的clone()方法來執行這項操作。clone()方法被定義為受保護方法,但你必須在你希望克隆的所有子類中重新公開定義它。例如,標准庫類ArrayList忽略clone(),但你可以這樣為ArrayList調用clone()方法:import java.util.*;class MyInt {private int i;public MyInt(int ii) { i = ii; }public void increment() { i++; }public String toString() {return Integer.toString(i);}}public class Test {public static void main(String[] args) {ArrayList al = new ArrayList();for(int i = 0; i < 10; i++ )al.add(new MyInt(i));ArrayList al1 = (ArrayList)al.clone();// Increment all al1』s elements:for(Iterator e = al1.iterator(); e.hasNext(); ) ((MyInt)e.next()).increment();}}clone()方法生成一個Object,它必須重新轉變為適當的類型。這個例子說明ArrayList的clone()方法如何不能自動克隆ArrayList包含的每一個對象?原有ArrayList和克隆後的ArrayList是相同對象的別名。這種情況通常叫做淺拷貝,因為它僅僅復制一個對象的「表面」部分。實際的對象由這個「表面」,引用指向的所有對象,以及那些對象指向的所有對象等構成。這往往被稱作「對象網路」。下一頁>>
『叄』 Java中是如何實現克隆
java 實現clone對象方法的步驟如下:
(1)實現Cloneable介面
(2)重載Object類中的clone()方法,重載時需定義為public
(3)在重載方法中,調用super.clone()
例如:
class CloneClass implements Cloneable {
public int aInt;
public Object clone() {
CloneClass o = null;
try {
o = (CloneClass) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}