2016-08-12 6 views
-4

このクラスは不変ですか?このクラスは不変ですか?

私はおおよそ "効果的なJava"、 "Item 15:Minimize mutability"のガイドラインに従おうとしているので、そのクラスは意図的に "最終的"ではありません。

public class Result<T extends Number> { 
    private final Map<String, T> result; 

    private Result(final Map<String, T> result) { 
     this.result = result; 
    } 

    public static final Result<? extends Number> of() { 
     return new Result<>(new LinkedHashMap<>()); 
    } 

    /** Add or replace value. */ 
    public Result<T> put(final String key, final T value) { 
     result.put(key, value); 
     return new Result<>(Collections.unmodifiableMap(result)); 
    } 

    public T get(final String key) { 
     return Collections.unmodifiableMap(result).get(key); 
    } 

    @Override 
    public String toString() { 
     return result.toString(); 
    } 
} 
+5

この行 'result.put(キー、値)を使って' result'マップを変更したため、私は、ないと思います; 'PUT'方法は、それを修正' –

+3

号。それが不変であるようにするには、オリジナルのものではなく、新しい 'Result'だけを異なるものにする必要があります。補足として、別の 'put'によって返された' Result'に 'put'を呼び出すと、例外がスローされます。 – resueman

+0

あなたはそれが不変であったと思いますか?不変の定義は何であると思いますか? –

答えて

4

put方法は、そのコピーにputを呼び出し、Mapのコピーを作成し、コピーされたマップを構築し、新たなResultを返す必要があります。

/** Add or replace value. */ 
public Result<T> put(final String key, final T value) { 
    Map<T> copy = new LinkedHashMap<>(result); 
    copy.put(key, value); 
    return new Result<>(copy); 
} 

実装もNumberが不変であることのすべてのサブクラスに依存していることに注意してください。それ以外の場合は、getメソッドの実装にも問題があります。

public T get(final String key) { 
    //Relies on T being immutable 
    return result.get(key); 
} 
+2

'また、実装はNumberが不変であるすべてのサブクラスに依存するか、またはディープコピーを作成することに注意してください。 –

+0

ありがとう@AlekseiBulgak、メモを追加しました。 –

関連する問題