999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

如何進行Java對象的克隆

2011-12-31 00:00:00錢宇虹
軟件工程 2011年10期

摘要:由于Java中的對象使用引用類型,所以沒有直接的方法可以將對象的內容復制到一個新的對象。雖然java.lang.Object類的clone()方法為所有的引用類型提供了一套標準的克隆機制,但是對于深度克隆是較為麻煩的。本文給出了采用clone()方法實現淺克隆的案例,指出其局限性,然后提出采用序列化實現深克隆的方法和代碼,最后指出了這種方法的缺陷。

關鍵詞:Java對象; 淺克隆;深克隆;Clonable接口 ;Serializable接口

在Java中,對象是通過引用變量(reference variables)進行操縱的。同一個對象可以有多個引用變量引用它,將一個引用變量賦給另一個引用變量,只是創建了一個新的引用,其結果是這兩個引用變量引用了同一個對象,而并沒有對這個對象進行拷貝[1]。

有時候,我們需要獲得一個對象的拷貝。例如,你需要修改某個對象,但你不知道還有誰可能有一個對它的引用,于是你將這個對象進行拷貝然后修改它。更為常見的情形是,當一個對象是一個公共方法的參數或返回值時,如果該對象是一個參數,你把它保存起來,不希望調用者可以對其進行修改,所以,你需要保存該對象的拷貝。同樣,如果該公共方法返回一個對象,它是你的類的內部狀態的一部分,這時你需要返回一個拷貝,從而避免調用者有意或無意地改變類的內部狀態。

由于Java中的對象使用引用類型,所以沒有直接的方法可以將對象的內容復制到一個新的對象。為此,Java提供了一個特殊的clone()方法,為所有的引用類型提供了一套標準的克隆機制。下面是我們需要了解的一些細節。

1 Object類的 clone()方法

java.lang.Object類的clone()方法提供了克隆的功能,這個方法被定義為protected。眾所周知,Object類是所有類的父類,所有類都繼承了這個類的方法。但是,這個方法的缺省實現會拋出CloneNotSupportedException異常。一個類要實現克隆必須重寫Object類的clone()方法。請記住,第一,你一定要把它顯式地改為public;第二,要實現Cloneable接口的類才可以被克隆。

圖1展示了一個可以克隆自己的Person類。該類只有一個屬性變量name,在它的clone()方法中,首先創建了一個Person對象obj,然后使它跟自己具有相同的name 值,最后返回對象obj。在調用clone()方法的地方,返回的新對象必須通過類型轉換,轉換成正確的類型。

圖2的代碼片斷演示了smith對象復制它自己得到smith2 .

圖3運行結果顯示,smith和smith2這兩個對象具有完全相同的name值Smith,但是smith和smith2是兩個完全不同的引用, 一個是c17164, 另一個是1fb8ee3, 這說明smith和smith2是兩個不同的對象。

2 淺克隆和深克隆

Java支持兩種類型的克隆:淺克隆(Shallow cloning)和深克隆(Deep cloning)。

淺克隆,就是克隆對象的所有變量都含有與原對象相同的值,而它對其他對象的引用都仍然指向原來的對象。換句話說,淺克隆僅僅克隆所考慮的對象,而不克隆它所引用的對象。

深克隆,就是克隆對象的所有變量都含有與原對象相同的值,并且它所有的對其他對象的引用不再是原有的,而是指向被復制過的新對象。換言之,深克隆把對象的所有引用的對象也都復制了一遍。

缺省方式下Java使用的是淺克隆。Object類提供的clone()方法實現的就是淺克隆。

標準庫類ArrayList重寫了clone()方法復制它自己,下面的案例驗證了ArrayList實現的也是淺克隆。

//list1有兩個student對象,他們的名字分別為//Robert和Jason

ArrayList list1 =

new ArrayList();

list1.add(new Student(\"Robert\"));

list1.add(new Student(\"Jason\"));

//復制list1,得到list2

ArrayList list2 =

(ArrayList)list1.clone();

//將list2中第一個student的名字更新為Rose

list2.get(0).setName(\"Rose\");

//查看list1中第一個student的名字

System.out.println(list2.get(0).getName());

結果顯示:我們將list2中第一個student的名字更新為Rose之后,list1中第一個student名字也隨之更新了。 這說明克隆出來的list和原來list里面的東西是同一個對象。

3 用序列化實現深克隆

我們在重寫clone()方法的時候,可以人為地添加對引用對象的復制,從而實現深克隆。但是,這個方法的缺點是太麻煩了,特別是當引用對象有很多,或者引用套引用很多重的時候。

業界常用的方法是使用序列化然后反序列化的方法來實現深克隆。由于序列化后,對象寫到流中,所有引用的對象都包含在其中,反序列化后,對等于生成了一個完全克隆的對象。

這個方法要求對象(包括被引用對象)必須事先實現了Serializable接口。

圖6所示的User 類包含一個屬性變量 name和一個對Address的引用變量address。為了節省篇幅,其中的setter/getter方法都沒有展開。請注意其中的copy()方法的具體實現,它首先將對象寫在字節流里, 然后再從字節流里面讀出來,得到一份克隆對象。

下面的代碼片斷演示了對一個User對象的深克隆。其中 smith2 是通過 smith 克隆的。

//用戶 smith, 地址在US

User smith = new User(\"Smith\",

new Address(\"US\"));

//復制smith,得到smith2

User smith2 = (User)smith.copy();

//分別打印smith 和 smith2 兩個引用

System.out.println(smith);

System.out.println(smith2);

//分別打印smith 和 smith2 包含的地址引用

System.out.println(smith.getAddress());

System.out.println(smith2.getAddress());

//分別打印smith 和 smith2的名字和地址值

System.out.println(smith.getName() +\",\"+smith.getAddress().getAddressName());

System.out.println(smith2.getName()+\",\"+smith2.getAddress().getAddressName());

結果顯示,smith 和 smith2 是兩個不同的引用,它們的值分別為173a10f和e09713, 而它們包含的地址引用也不同,分別為530daa和de6f34,但是它們的name值和addressName值是相同的。

4 結語

要實現Java對象的深克隆,我們可以采用重寫Object類的clone ()方法,或者業界廣泛采用的序列化方法。重寫clone()方法不適合于引用對象很多,或者引用套引用很多重的情況。而序列化方法很好地解決了這個問題。 但是序列化方法存在以下缺陷:首先是性能問題,人們發現序列化方法比一個正確實現的clone()方法要慢一百倍。其次,并不是所有的對象都是可序列化的。第三,要當心transient變量,這些變量不被序列化,在反序列化時,采用的是默認值[2]。

參考文獻

[1] 錢宇虹,論Java對象的比較技巧,[J],軟件工程師, 2010.8

[2] Eamonn McManus,Cloning Java objects using serialization [EB], http://weblogs.java.net/blog/emcmanus/archive/2007/04/cloning_java_ob.html 2007

主站蜘蛛池模板: 嫩草影院在线观看精品视频| 国产色爱av资源综合区| 日本免费福利视频| 亚洲一区二区无码视频| 91午夜福利在线观看| 国禁国产you女视频网站| 热这里只有精品国产热门精品| 天天摸天天操免费播放小视频| 久青草免费在线视频| 精品国产成人国产在线| 成人福利在线看| 国产老女人精品免费视频| 欧美亚洲另类在线观看| 尤物在线观看乱码| 亚洲国产成人自拍| 精品一区二区三区视频免费观看| 97超碰精品成人国产| 国产精品美乳| 久久99热这里只有精品免费看| 永久免费AⅤ无码网站在线观看| 精品视频免费在线| 国产美女一级毛片| 日本不卡免费高清视频| 九九热精品免费视频| 国产一区在线视频观看| 少妇人妻无码首页| 国产精品一区在线观看你懂的| 久久国产精品影院| 99尹人香蕉国产免费天天拍| 亚洲视频无码| 国产91九色在线播放| 国产69精品久久久久孕妇大杂乱 | 伊人久久大香线蕉影院| 午夜视频免费试看| 日韩欧美在线观看| 国产成人成人一区二区| 9cao视频精品| 99在线视频精品| 首页亚洲国产丝袜长腿综合| 激情综合激情| 欧美影院久久| 亚洲成a人片在线观看88| 国产一级在线播放| 亚洲成人网在线播放| 国产肉感大码AV无码| 久热这里只有精品6| 日韩在线影院| 97国产一区二区精品久久呦| 制服丝袜 91视频| 欧美成人亚洲综合精品欧美激情| 亚洲人成人伊人成综合网无码| 99精品福利视频| 国产精品va免费视频| 国产精品毛片一区视频播| 成人免费网站久久久| 国产毛片基地| 成年A级毛片| 亚洲中文制服丝袜欧美精品| 亚洲国产天堂久久综合226114 | 影音先锋亚洲无码| 中国丰满人妻无码束缚啪啪| 99在线观看国产| 午夜精品区| 日韩 欧美 小说 综合网 另类| 91免费在线看| 国产成人无码AV在线播放动漫 | 亚洲69视频| 久久精品中文字幕免费| 香港一级毛片免费看| 99久久精品久久久久久婷婷| 91丝袜在线观看| 欧美午夜在线观看| 国产欧美日韩综合在线第一| 久热re国产手机在线观看| 国产黄网站在线观看| 18禁色诱爆乳网站| 色综合成人| 国产一级毛片高清完整视频版| 91色在线视频| 免费人成在线观看成人片 | 亚洲男人的天堂在线观看| 狠狠躁天天躁夜夜躁婷婷|