Java以编程方式强制执行

时间:2013-05-08 13:07:48

标签: java final

确保值只设置一次的正确方法是什么,尽管设置的时间是未知的(即:不在构造函数中)。我可以进行空检查或跟踪标志并抛出异常 - 但我应该抛出什么异常?这是一个小型的本地化库,我不想为这种看似通用的案例创建自己的ValueAlreadyAssigned异常。

3 个答案:

答案 0 :(得分: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.
    }
}

答案 1 :(得分:4)

该方法可以抛出IllegalStateException,因为它是javadocs说:

  

表示某个方法已在非法不合适的情况下被调用   时间。

答案 2 :(得分:1)

恕我直言,你自己的例外定义并不是什么大问题,特别是如果它延伸RuntimeException。所以我建议您定义ValueAlreadySetException extends IllegalStateException并使用它。

下一点是根据@ Renan的建议,你必须复制的每个setter的逻辑。我建议你以下。定义特殊的通用容器并使用它:

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();
    }
}

实现被封装到一点。如果需要,您可以在一个地方更改它。也支持空值。制定者和吸气者比普通人更复杂一点。