第11條 謹慎地覆蓋clone

2022-07-22 07:00:16 字數 2250 閱讀 3191

cloneable介面表明這樣的物件時允許轉殖的,但這個介面並沒有成功達到這個目的,主要是因為它缺少乙個clone方法,object的clone方法是受保護的。如果不借助反射,就不能僅僅因為乙個物件實現了colneable就可以釣魚clone方法,即使是反射呼叫也不能保證這個物件一定具有可訪問clone方法。

既然cloneable並沒有包含任何方法,那麼它到底有什麼用呢?它其實覺得了object中受保護的clone方法實現的行為,如果乙個類實現了cloneable那麼object的clone方法就返回該物件的逐域拷貝,否則會丟擲clonenotsupportedexception。但真說介面一種極端非典型用法,不值得提倡。

如果實現cloneable介面是要對某個類起到作用,類和它的所有超類都必須遵守乙個一定協議,言外之意就是無需呼叫構造器就可以建立物件。

clone它的通用約定非常弱:

建立和返回該物件的乙個拷貝。這個拷貝的精確含義取決於該物件的類。一般含義是,對於任何物件x,表示式x.clone() != x 將會是true,並且,表示式x.clone().getclass() == x.getclass() 將會是true,但這些不是絕對的要求,通常情況下,表示式x.clone().equals(x) 將會是true,這也不是乙個絕對的要求,拷貝物件往往是建立它的類的乙個新例項,但它同時也會要求拷貝內部的資料結構。

這時候,如果類的每個域包含乙個基本型別的值,或者包含乙個指向不可變物件的引用,那麼被返回的物件則正是所需要的物件,只需要簡單地呼叫super.clone() 而不用做進一步的處理。但是!如果物件中其他物件的引用時,那麼只是簡單的clone就無法做到完全的轉殖了,下面的例子我們就可以體會到

從結果上我們可以看出,s2對s1進行轉殖時,對s1的屬性professor p並沒有進行轉殖,導致s1和s2對其引用指向同乙個,這會造成s2若改變了值,s1則也被動改變了。那應該如何實現深層次的轉殖,即修改s2的教授不會影響s1的教授?其實很簡單,只需要對professor進行修改,如下所示即可

class professor  implements

cloneable

public

object clone()

catch

(clonenotsupportedexception e)

return

o; }

}

修改professor後,還需要在student的clone方法中加入一句**:o.p=(professor)p.clone(); 

看到結果就如我們所希望的那樣。因此,在使用clone時,一定要分清需要轉殖的物件屬性。

Java學習筆記 11 謹慎地覆蓋clone

1 clone方法的通用約定是非常弱的 x.clone x x.clone getclass x.getclass x.clone equals x 都不是絕對的要求 2 clone方法就是另乙個構造器,你必須保證它不會傷害到原始的物件,並確保正確地建立被轉殖物件中的約束條件。3 clone架構與應...

Java學習筆記 謹慎地覆蓋clone

1 clone方法的通用約定是非常弱的 x.clone x x.clone getclass x.getclass x.clone equals x 都不是絕對的要求 2 clone方法就是另乙個構造器,你必須保證它不會傷害到原始的物件,並確保正確地建立被轉殖物件中的約束條件。3 clone架構與應...

謹慎的覆蓋clone 方法

如果乙個類實現了cloneable方法,就可以呼叫clone方法,並且返回該物件的逐域拷貝,否則丟擲clonenotsupportedexception異常。下面是乙個演示clone方法的類,注意深度拷貝問題 public class testclone implements cloneable o...