如何允许在 java 中仅设置一次变量

How to allow variables being set only once in java

我需要在 java 中实现一个 class,它的字段只需要设置一次,但它的值在字段声明时是未知的。为此,我有:

public class MyClass {
    private String field1 = null;
    public void setField1(String value) {
        if (field1 == null) {
            field1 = value;
        }
     }
}

然而,我所拥有的并不能阻止用户多次调用 setField1。这可能会导致用户试图设置它(不知道它已在其他地方设置)的混乱,然后用户会因为 field1 没有给出他们设置的值而感到困惑 - 直到他们进入setField1 方法看看发生了什么。

我不喜欢的另一个解决方案是创建一个构造函数来接收 field1 的值,然后不提供 setter。因为它使 class 更难扩展,所以当需要多个 String 字段时 - 在这种方法中,构造函数将需要接受一对 String 作为参数,然后用户可以如此容易混淆 by/missing 参数。

而且显然将 field1 设置为 final 也不起作用。

我应该怎么做才能防止我上面提到的问题?

这种情况下的常见做法是抛出 RuntimeException。在你的情况下 IllegalStateException 最适合:

public void setField1(String value) {
    if (field1 != null) {
        throw new IllegalStateException("setField1 was already called");
    }
    field1 = Objects.requireNonNull(value);
}

另请注意,最好检查传递的字符串是否为空(我为此添加了 Objects.requireNonNull)。

您无法在编译时控制它,因为在没有实际 运行 程序的情况下,无法分析程序以准确说明该方法是否被调用一次或多次。

您通常应该在这种情况下使用构建器模式:https://en.wikipedia.org/wiki/Builder_pattern

MyClass instance = (new MyClassBuilder())
    .setField1(...)
    .setField2(...)
    .build();

您的构建器对象允许您设置您喜欢的所有字段和选项,但它构建的 MyClass 实例不能。