Roger Tu

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

             ::  :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            7 隨筆 :: 0 文章 :: 19 評論 :: 0 Trackbacks

          1 ???????? 什么是 Clone ,容易實現嗎?

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

          型相同( o.getClass() == o’.getClass() ),內容相同(對于 o/o’ 中的字段 f ,如果 f 是基本數據類型,則 o.f == o’.f ;如果 f 是對象引用,則 o.f == o’.f o.f 指向的對象與 o’.f 指向的對象的內容相同)。通常稱 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;

          ??? }

          }

          ?

          然而,稍加推敲,就會發現這樣的實現方法有兩個問題:

          1.???????? 要想某個類有 clone 功能,必須單獨為其實現 clone() 函數,函數實現代碼與該類定義密切相關。

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

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

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

          protected native Object clone() throws CloneNotSupportedException;

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

          與具體平臺相關的底層工作。

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

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

          public interface Cloneable {

          }

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

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

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

          2.???????? Override Object clone() 方法,在該方法中調用 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 ,如何為其克隆(副

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

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

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

          ?????? Java Collection 類庫中具體數據結構類( ArrayList/LinkedList HashSet/TreeSet HashMap/TreeMap 等)都具有克隆功能,且都是 Shallow Clone ,這樣設計是合理的,因為它們不知道存放其中的每個數據對象是否也有克隆功能。 System.arrayCopy() 的實現采用的也是 Shallow Clone

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

          class ImmutableClass {

          ?????? MutableClass m;

          ImmutableClass(MutableClass m) {

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

          }

          public MutableClass getM() {

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

          }

          }

          ?

          ??????

          3.2 ??? 如何實現 Deep Clone

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

          如果有,確保包含的可變類本身都實現了 Deep Clone

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

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

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

          返回 o

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

          評論

          # re: Java Clone機制 2007-03-18 18:54 BeanSoft
          受益了...  回復  更多評論
            

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

          # re: Java Clone機制 2008-05-01 21:08 adousen
          很精彩  回復  更多評論
            

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

          我覺得應該改成這樣:
          a.field1=this.field1;
          a.field2=this.field2;

            回復  更多評論
            


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


          網站導航:
           
          主站蜘蛛池模板: 右玉县| 昌平区| 长兴县| 罗江县| 泗水县| 榆社县| 兴业县| 旬阳县| 巴彦县| 乐陵市| 遂平县| 南部县| 武汉市| 荥经县| 从江县| 师宗县| 湖南省| 黑水县| 南澳县| 黄浦区| 油尖旺区| 元阳县| 遂平县| 东乌珠穆沁旗| 万源市| 肇州县| 灵川县| 育儿| 上犹县| 庆城县| 都昌县| 河西区| 屯昌县| 体育| 常山县| 涪陵区| 花莲县| 绍兴市| 思茅市| 洛南县| 永昌县|