3 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
在Java中復(fù)制對(duì)象的所有方法都有嚴(yán)重的缺陷:
克隆
clone()方法受到保護(hù),因此除非有問題的類使用公共方法覆蓋它,否則不能直接調(diào)用它。
clone()不會(huì)調(diào)用構(gòu)造函數(shù)。任何構(gòu)造函數(shù)。它將分配內(nèi)存,分配內(nèi)部class字段(您可以通過其讀取getClass())并復(fù)制原始字段。
有關(guān)clone()的更多問題,請(qǐng)參閱Joshua Bloch的書“ Effective Java,Second Edition ”的第11項(xiàng)
連載
序列化更糟糕; 它有許多缺點(diǎn),clone()然后有一些缺陷。約書亞有一整章只有四個(gè)項(xiàng)目。
我的解決方案
我的解決方案是為我的項(xiàng)目添加一個(gè)新界面:
public interface Copyable<T> {
T copy ();
T createForCopy ();
void copyTo (T dest);
}
代碼如下所示:
class Demo implements Copyable<Demo> {
public Demo copy () {
Demo copy = createForCopy ();
copyTo (copy);
return copy;
}
public Demo createForCopy () {
return new Demo ();
}
public void copyTo (Demo dest)
super.copyTo (dest);
...copy fields of Demo here...
}
}
不幸的是,我必須將此代碼復(fù)制到我的所有對(duì)象,但它始終是相同的代碼,因此我可以使用Eclipse編輯器模板。好處:
我可以決定調(diào)用哪個(gè)構(gòu)造函數(shù)以及如何初始化哪個(gè)字段。
初始化以確定性順序發(fā)生(根類到實(shí)例類)
我可以重用現(xiàn)有的對(duì)象并覆蓋它們
輸入安全
單身人士留著單身人士
對(duì)于標(biāo)準(zhǔn)Java類型(如集合等),我使用可以復(fù)制它們的實(shí)用程序類。這些方法有標(biāo)記和回調(diào),所以我可以控制副本的深度。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
淺克隆的集合是很容易的,但如果你想深克隆,圖書館可能會(huì)做你比手更好的編碼它(因?yàn)橐寺〉脑乩锩婕蠟楹茫?/p>
就像這個(gè)答案一樣,我使用了Cloner庫,并專門針對(duì)XStream進(jìn)行了性能測試(可以通過序列化然后反序列化來克隆')和二進(jìn)制序列化。雖然XStream在向/從xml序列化方面非???,但克隆在克隆方面要快得多:
0.0851 ms:xstream(通過序列化/反
序列化克?。?.0223 ms:二進(jìn)制序列化(通過序列化/反序列化克?。?/p>
0.0017 ms:cloner
* 克隆一個(gè)簡單對(duì)象(兩個(gè)字段)的平均時(shí)間,沒有默認(rèn)的公共構(gòu)造函數(shù)。運(yùn)行10,000次。
除了快速,這里有更多選擇克隆人的理由:
執(zhí)行任何對(duì)象的深度克?。词故悄切┠阕约翰粚懙膶?duì)象)
每次添加字段時(shí),都不必使clone()方法保持最新
您可以克隆沒有默認(rèn)公共構(gòu)造函數(shù)的對(duì)象
適用于Spring
(優(yōu)化)不克隆已知的不可變對(duì)象(如Integer,String等)
使用方便。例:
cloner.deepClone(anyObject);
添加回答
舉報(bào)