4

値が設定される時間は不明ですが(つまり、コンストラクターではありません)、値が一度だけ設定されるようにする適切な方法は何ですか。null チェックを実行するか、フラグを追跡して例外をスローすることはできますが、どの例外をスローする必要がありますか? これは小さなローカライズされたライブラリ用であり、私はこのような一見一般的なケースに対して独自の ValueAlreadyAssigned 例外を作成したくありません。

4

3 に答える 3

8

セッターで。次のようにします。

private foo bar;

public void setFoo(foo bar) {
    if (this.bar == null) {
        this.bar = bar;
    } else {
        System.out.println("Don't touch me!");
        // J/K Throw an IllegalStateException as Michal Borek said in his answer.
    }
}
于 2013-05-08T13:10:42.977 に答える
4

IllegalStateExceptionjavadocs が言うので、メソッドは をスローする可能性があります。

メソッドが違法で不適切な時間に呼び出されたことを通知します。

于 2013-05-08T13:09:59.113 に答える
1

あなた自身の例外のIMHO定義は、特にそれが拡張されている場合は大したことではありませんRuntimeException。したがって、それを定義して使用することをお勧めしますValueAlreadySetException extends IllegalStateException

次のポイントは、@Renan の提案に従って複製する必要がある各セッターへのロジックです。以下をお勧めします。特別なジェネリック コンテナーを定義して使用します。

public class SetOnceContainer<T> {
    private Class<T> type;
    private String name;
    private T value;
    private boolean set = false;

    public SetOnceContainer(Class<T> type, String name) {
        this.type = type;
        this.name = name;
    }

    public void set(T value) {
        if (set) {
             throw new ValueAlreadySetException(name);
        }
        this.value = value;
        this.set = true;
    }
    public T get() {
        return value;
    }
}

nullこの実装は値もサポートすることに注意してください。

これで、次のように使用できます。

public MyClass {
    private SetOnceContainer<Integer> number = new SetOnceContainer<Integer>(Integer.class, "number");
    private SetOnceContainer<String> text = new SetOnceContainer<String>(String.class, "text");


    public void setNumber(int value) {
        number.set(value);
    }
    public void setText(String value) {
        text.set(value);
    }
    public Integer getNumber() {
        return number.get();
    }
    public String getText() {
        text.get();
    }
}

実装は 1 つのポイントにカプセル化されます。必要に応じて一度に変更できます。Null 値もサポートされています。セッターとゲッターは、通常のものより少しだけ複雑です。

于 2013-05-08T13:27:53.640 に答える