天天看點

推薦使用序列化實作對象的拷貝

上一個建議說了對象的淺拷貝問題,實作Cloneable接口就具備了拷貝能力,那我們來思考這樣一個問題:如果一個項目中有大量的對象是通過拷貝生成的,那我們該如何處理?每個類都寫一個clone方法,并且還要深拷貝?想想看這是何等巨大的工作量呀,是否有更好的方法呢?

其實,可以通過序列化方式來處理,在記憶體中通過位元組流的拷貝來實作,也就是把母對象寫到一個位元組流中,再從位元組流中将其讀出來,這樣就可以重建一個新對象了,該新對象與母對象之間不存在引用共享的問題,也就相當于深拷貝了一個新對象,代碼如下:

推薦使用序列化實作對象的拷貝
推薦使用序列化實作對象的拷貝

此工具類要求被拷貝的對象必須實作Serializable接口,否則是沒辦法拷貝的(當然,使用反射那是另外一種技巧),上一個建議中的例子隻要稍微修改一下即可實作深拷貝,代碼如下:

推薦使用序列化實作對象的拷貝
推薦使用序列化實作對象的拷貝

上去的,然後我們就可以通過CloneUtils工具進行對象的深拷貝了。用此方法進行對象拷貝時需要注意兩點:

(1)對象的内部屬性都是可序列化的

如果有内部屬性不可序列化,則會抛出序列化異常,這會讓調試者很納悶:生成一個對象怎麼會出現序列化異常呢?從這一點來考慮,也需要把CloneUtils工具的異常進行細化處理。

(2)注意方法和屬性的特殊修飾符

比如final、static變量的序列化問題會被引入到對象拷貝中來(參考第1章),這點需要特别注意,同時transient變量(瞬态變量,不進行序列化的變量)也會影響到拷貝的效果。

當然,采用序列化方式拷貝時還有一個更簡單的辦法,即使用Apache下的commons工具包中的SerializationUtils類,直接使用更加簡潔友善。

本文轉自SummerChill部落格園部落格,原文連結:http://www.cnblogs.com/DreamDrive/p/5430981.html,如需轉載請自行聯系原作者