2010-06-02 45 views
3

如何使一個可變對象的防禦副本在不可變對象中包含可變字段?如何製作對象的防禦副本?

class ImmutableObject { 

    private final MutableObject immutable_field; 

    ImmutableObject(MutableObject y) { 
    this.immutable_field = y; 
    } 
} 

class MutableObject { 

    public int mutable_field; 
} 
  • 的MutableObject沒有一個構造函數,讓我設定的領域。
  • MutableObject的當前狀態應該在不可變對象中捕獲並且永遠不會改變。
+1

對不起,我的無知,但什麼是對象的「防禦副本」?什麼是用例? – 2010-06-02 03:28:32

+2

它不是真正的不可變的,如果它包含一個可變對象嗎?......你將不會擁有不可變對象帶來的安全性和併發性。 – Artefacto 2010-06-02 03:29:27

+0

即使我認爲immutable_field不能被訪問,如果有人改變了MutableObject,我的字段也會改變。這就是爲什麼我需要創建一個對象的副本,以便它指向一個無法訪問的新對象。這被稱爲「防禦性複製」。 – unj2 2010-06-02 03:31:27

回答

7

你需要做的是在

MutableObject return_immutable_field() { 
    return immutable_field; 
    } 

更改爲:

MutableObject return_immutable_field() { 
    MutableObject tmp = new MutableObject(); 
    tmp.mutable_field = immutable_field.mutable_field; 
    return tmp; 
    } 

有關說明見http://www.javapractices.com/topic/TopicAction.do?Id=15

+0

問題不是在返回時,而是在構造時。 – unj2 2010-06-02 03:41:33

+1

@OP:無論如何,它基本上是一樣的。 – 2010-06-02 03:57:50

4

好吧,假設有什麼工作要做約可變對象類的聲明,可以利用反射(Class,newIntance()ClassgetFields())創建一個新的對象並複製字段值。您也可以以這種方式實施深層複製。如果類支持序列化,那麼另一個駭客方法是序列化對象,然後保存反序列化的副本。如果可以修復可變對象的設計,那將是一個更好的方法。

編輯
對於你給的具體示例中,羅曼的答案你想要做什麼。如果你有一個通用的可變對象,它沒有提供複製它的機制,並且直到後來才知道類型,那麼反射方法就是如何實現複製機制。

+0

謝謝,涵蓋了問題的其他部分。 +1 – 2010-06-02 04:06:59

相關問題