2014-02-12 27 views
7

請考慮下面的例子:數子類的防禦性複製

public final class ImmutableWrapper<T extends Number> { 

    private final T value; 

    public ImmutableWrapper(T value) { 
     // a subclass of Number may be mutable 
     // so, how to defensively copying the value? 
     this.value = value; 
    } 

    public T getValue() { 
     // the same here: how to return a copy? 
     return value; 
    } 
} 

爲了使這個類不可變的,我必須防守複製傳遞給構造任何可變參數,創建內部可變對象的副本公共返回方法。

這可能嗎?如果沒有,是否有任何解決方法?

+0

你爲什麼要這麼做?在javadoc中聲明如果數字發生了變異,那麼在多線程上下文中該類的行爲是未定義的嗎? – assylias

+1

@assylias例如,我在Guava的[Range](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Range.html)中看到了關於傳遞可變對象的警告到javadoc中的構造函數。無論如何,這是我的最後一個選擇。 –

+0

除非你害怕惡意代碼搞亂你的代碼,否則這是一個完全合理的選擇。 – assylias

回答

3

由於所有Number s爲Serializable您可以通過serializing/deserializing創建副本它們。

也許你可以使用apache commons-lang的SerializationUtils.clone(Serializable)

public final class ImmutableWrapper<T extends Number> { 

    private final T value; 

    public ImmutableWrapper(T value) { 
     // a subclass of Number may be mutable 
     // so, how to defensively copying the value? 
     this.value = SerializationUtils.clone(value); 
    } 

    public T getValue() { 
     // the same here: how to return a copy? 
     return SerializationUtils.clone(value); 
    } 
} 

,或者如果你想自己實現它看看:

0

您需要克隆該對象。所以,你的代碼看起來像:

public final class ImmutableWrapper<T extends Number> { 
    private final T value; 

    public ImmutableWrapper(T value) { 
     this.value = value.clone(); 
    } 

    public T getValue() { 
     return value.clone(); 
    } 
} 
+0

但是'T extends Number'和'java.lang.Number'沒有公共方法'clone'。你如何編譯這個例子? –

+0

並且Number不實現Cloneable。 – assylias

+0

只是將其粘貼到日食中。編譯器對'value.clone()'不滿意,因爲'clone()'在'Object'上不可見。 – Harald