java字符串深克隆_Java中对象的深复制(深克隆)和浅复制(浅克隆)之序列化...
1.淺復制與深復制概念
⑴淺復制(淺克隆)
被復制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。換言之,淺復制僅僅復制所考慮的對象,而不復制它所引用的對象。
舉例說明:
常見的List的克隆方式有很多,下面我們來列舉幾種常見的List淺復制的方式:
public static void main(String []args){
List> list1 = new ArrayList>(); Map map = new HashMap();
map.put("name", "xiaoming");
map.put("age", "28");
list1.add(map); //克隆方法1:利用原list1作為參數直接構造方法生成。 List> list2 = new ArrayList>(list1); //克隆方法2:手動遍歷將原list1中的元素全部添加到復制表中。 for(int i = 0, l = list1.size(); i < l; i++)
list2.add(list1.get(i)); //克隆方法3:調用Collections的靜態工具方法 Collections.copy //克隆方法4:使用System.arraycopy方法進行復制 }
List自身是一個對象,他在存儲類類型的時候,只負責存儲地址。而存儲基本類型的時候,存儲的就是實實在在的值。縱然你有千千萬萬個List,元素還是那么幾個。無論是重新構造,Collections的復制方法,System的復制方法,還是手動去遍歷,結果都一樣,這些方法都只改變了ArrayList對象的本身,簡單的添加了幾個指向老元素的地址。而沒做深層次的復制。(及壓根沒有沒有 new新對象 的操作出現。)
有的時候我們確實需要將這些元素也都復制下來而不是只是用原來內存中的元素。List層實現這個問題。java語言設計之初就考慮進去了,避免操作這些埋在堆內存中的數據,所有操作都去針對能找到他們的地址。地址沒了自身還會被GC干掉。所以只好一點點的去遍歷,new創建新的對象并賦予原來的值。據說可能覺得上述的做法略微調整,所以巧用序列化對象讓這些數據在IO流中跑了一圈,可以實現復制。其實把對象序列化到流中,java語言實在是妥協了,畢竟你不能再把地址扔進去吧?再說了io流是要和別的系統交互的,你發給別人一個地址讓別人去哪個堆里找?所以不用多提肯定要新開辟堆內存的。
⑵深復制(深克隆)之序列化
被復制對象的所有變量都含有與原來的對象相同的值,除去那些引用其他對象的變量。那些引用其他對象的變量將指向被復制過的新對象,而不再是原有的那些被引用的對象。換言之,深復制把要復制的對象所引用的對象都復制了一遍。
Java中利用串行化來做深復制(深克隆)(避免重寫比較復雜對象的深復制的clone()方法,也可以程序實現斷點續傳等等功能)
把對象寫到流里的過程是串行化(Serilization)過程,但是在Java里又非常形象地稱為“冷凍”或者“腌咸菜(picking)”過程;而把對象從流中讀出來的并行化(Deserialization)過程則叫做
“解凍”或者“回鮮(depicking)”過程。
應當指出的是,寫在流里的是對象的一個拷貝,而原對象仍然存在于JVM里面,因此“腌成咸菜”的只是對象的一個拷貝,Java咸菜還可以回鮮。
在Java語言里深復制一個對象,常常可以先使對象實現Serializable接口,然后把對象(實際上只是對象的一個拷貝)寫到一個流里(腌成咸菜),再從流里讀出來(把咸菜回鮮),便可以重建對象。
如下為深復制源代碼。
public List> deClone(Object obj) throws IOException,OptionalDataException,ClassNotFoundException{
//將對象寫到流里
ByteArrayOutoutStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(obj);//從流里讀出來
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return(oi.readObject());
}
這樣做的前提是對象以及對象內部所有引用到的對象都是可串行化的,否則,就需要仔細考察那些不可串行化的對象或屬性可否設成transient,從而將之排除在復制過程之外。
總結
以上是生活随笔為你收集整理的java字符串深克隆_Java中对象的深复制(深克隆)和浅复制(浅克隆)之序列化...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux显示mem进行排序,Linux
- 下一篇: java des加密类_java的DES