<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Roger Tu

    A simple boy living a simple life in every simple day...

       ::  :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      7 隨筆 :: 0 文章 :: 19 評論 :: 0 Trackbacks

    1 ???????? 什么是 Clone ,容易實(shí)現(xiàn)嗎?

    簡單地說, Clone 就是對于給定的一個對象實(shí)例 o ,得到另一個對象實(shí)例 o’ o o’

    型相同( o.getClass() == o’.getClass() ),內(nèi)容相同(對于 o/o’ 中的字段 f ,如果 f 是基本數(shù)據(jù)類型,則 o.f == o’.f ;如果 f 是對象引用,則 o.f == o’.f o.f 指向的對象與 o’.f 指向的對象的內(nèi)容相同)。通常稱 o’ o 的克隆或副本。

    ?????? 直觀上看,似乎很容易為一個類加上 clone 方法:

    class A {

    ?????? private Type1 field1;

    ??? private Type2 field2;

    ???? …..

    ??? public Object clone() {

    ????????????? A a = new A();

    ??????? a.field1 = a.getField1();

    ??????? a.field2 = a.getField2();

    ??????? ……

    ??????? return a;

    ??? }

    }

    ?

    然而,稍加推敲,就會發(fā)現(xiàn)這樣的實(shí)現(xiàn)方法有兩個問題:

    1.???????? 要想某個類有 clone 功能,必須單獨(dú)為其實(shí)現(xiàn) clone() 函數(shù),函數(shù)實(shí)現(xiàn)代碼與該類定義密切相關(guān)。

    2.???????? 即使基類 A 已有 clone() 函數(shù),其子類 ExtendA 若要具備 clone 功能,則必須 override 其基類 A clone() 函數(shù)。否則,對類型為 ExtendA 的對象 ea clone() 方法的調(diào)用,會執(zhí)行于類 A 中定義的 clone() 方法而返回一個類型為 A 的對象,它顯然不是 ea 的克隆。

    2 ???????? Java clone 的支持

    萬類之初的 Object 類有 clone() 方法:

    protected native Object clone() throws CloneNotSupportedException;

    該方法是 protected 的,顯然是留待被子類 override 的。該方法又是 native 的,必然做了

    與具體平臺相關(guān)的底層工作。

    事實(shí)上,類 Object clone() 方法首先會檢查 this.getClass() 是否實(shí)現(xiàn)了 Cloneable 接口。

    Cloneable 只是一個標(biāo)志接口而已,用來標(biāo)志該類是否有克隆功能。

    public interface Cloneable {

    }

    ?????? 如果 this.getClass() 沒有實(shí)現(xiàn) Cloneable 接口, clone() 就會拋 CloneNotSupportedException 返回。否則就會創(chuàng)建一個類型為 this.getClass() 的對象 other ,并將 this field 的值賦值給 other 的對應(yīng) field ,然后返回 other

    ?????? 如此一來,我們要定義一個具有 Clone 功能的類就相當(dāng)方便:

    1.???????? 在類的聲明中加入“ implements Cloneable ”,標(biāo)志該類有克隆功能;

    2.???????? Override Object clone() 方法,在該方法中調(diào)用 super.clone()

    class CloneableClass implements Cloneable {

    ?????? ……

    public Object clone() {

    ?????? try {

    ?????? ?????? return super.clone(); // 直接讓 Object.clone() 為我們代勞一切

    ??? } catch (CloneNotSupportedException e) {

    ?????? ?????? throw new InternalError();

    ?????? }

    }

    }

    ?

    3 ???????? Shallow Clone Deep Clone

    3.1 ??? Shallow Deep 從何而來

    一個具有克隆功能的類,如果有可變( Mutable )類類型的字段 field ,如何為其克?。ǜ?/span>

    本)對象 o’ 中的 field 賦值?

    ?????? 方法一、如 Object clone() 方法所實(shí)現(xiàn):設(shè)原始對象為 o ,其克隆對象是 o’ ,執(zhí)行 o’.field = o.field 。這樣, o’.field o.field 指向同一個可變對象 m o o’ 可能會相互影響(一個對象的狀態(tài)可能會隨著另一個對象的狀態(tài)的改變而改變)。這樣的 Clone 稱為 Shallow Clone 。這也是 Object clone() 方法的實(shí)現(xiàn)方式。

    ?????? 方法二、將 o.field 指向的可變對象 m 克隆,得到 m’ ,將 m’ 的引用賦值給 o’.field 。這樣 o’ o 內(nèi)容相同,且相互之間無影響(一個對象狀態(tài)的改變不會影響另一個對象的狀態(tài))。這樣的 Clone 稱為 Deep Clone 。

    ?????? Java Collection 類庫中具體數(shù)據(jù)結(jié)構(gòu)類( ArrayList/LinkedList HashSet/TreeSet , HashMap/TreeMap 等)都具有克隆功能,且都是 Shallow Clone ,這樣設(shè)計(jì)是合理的,因?yàn)樗鼈儾恢来娣牌渲械拿總€數(shù)據(jù)對象是否也有克隆功能。 System.arrayCopy() 的實(shí)現(xiàn)采用的也是 Shallow Clone 。

    ?????? Deep Clone 對于實(shí)現(xiàn)不可變( Immutable )類很有幫助。設(shè)一個類包含可變類 M 類型的 field ,如何將其設(shè)計(jì)為不可變類呢?先為 M 實(shí)現(xiàn) Deep Clone 功能,然后這樣設(shè)計(jì)類 ImmutableClass

    class ImmutableClass {

    ?????? MutableClass m;

    ImmutableClass(MutableClass m) {

    ?????? this.m = m.clone(); // 將傳入的 m clone 賦值給內(nèi)部 m

    }

    public MutableClass getM() {

    ??? return this.m.clone(); // 將內(nèi)部 m clone 返回給外部

    }

    }

    ?

    ??????

    3.2 ??? 如何實(shí)現(xiàn) Deep Clone

    檢查類有無可變類類型的字段。如果無,返回 super.clone() 即可;

    如果有,確保包含的可變類本身都實(shí)現(xiàn)了 Deep Clone

    Object o = super.clone(); // 先執(zhí)行淺克隆,確保類型正確和基本類型及非可變類類型字段內(nèi)容正確

    對于每一個可變類類型的字段 field

    ?????? o.field = this.getField().clone();

    返回 o

    posted on 2007-03-18 03:11 RogerTu 閱讀(3056) 評論(4)  編輯  收藏 所屬分類: JAVA

    評論

    # re: Java Clone機(jī)制 2007-03-18 18:54 BeanSoft
    受益了...  回復(fù)  更多評論
      

    # re: Java Clone機(jī)制 2007-03-19 12:37 Tortoise
    不錯,頂  回復(fù)  更多評論
      

    # re: Java Clone機(jī)制 2008-05-01 21:08 adousen
    很精彩  回復(fù)  更多評論
      

    # re: Java Clone機(jī)制 2009-06-12 16:00 macleane
    請問這兩句代碼是什么意思
    a.field1 = a.getField1();
    a.field2 = a.getField2();

    我覺得應(yīng)該改成這樣:
    a.field1=this.field1;
    a.field2=this.field2;

      回復(fù)  更多評論
      


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲另类图片另类电影| 99999久久久久久亚洲| 黄色片免费在线观看| 亚洲黄色在线视频| 亚洲大香伊人蕉在人依线| 久久久久久久久免费看无码| 看成年女人免费午夜视频| 亚洲成亚洲乱码一二三四区软件| 亚洲国产精品免费观看| 免费无遮挡无遮羞在线看| 亚洲国产成人精品不卡青青草原| 在线观看人成网站深夜免费| 久草免费福利在线| 亚洲国产成人资源在线软件| 亚洲综合色在线观看亚洲| 麻豆视频免费观看| 国产精品福利片免费看| 亚洲色偷偷色噜噜狠狠99网| 亚洲亚洲人成综合网络| 最新仑乱免费视频| 精品视频一区二区三区免费| 亚洲av成人无码网站…| 亚洲色图黄色小说| 亚洲一本大道无码av天堂| 成年人在线免费观看| 无码精品一区二区三区免费视频 | 一本天堂ⅴ无码亚洲道久久| 国产av无码专区亚洲av果冻传媒| 国产桃色在线成免费视频 | 国产精品色午夜免费视频| 久久香蕉国产线看免费| 污视频网站免费在线观看| 亚洲国产日韩在线一区| 久久精品亚洲日本佐佐木明希| 宅男666在线永久免费观看| xx视频在线永久免费观看| 国产日韩久久免费影院| 美女露隐私全部免费直播| 激情五月亚洲色图| 亚洲视频欧洲视频| 久久久久无码精品亚洲日韩|