我需要在java中实现一个类,其中的字段只需要设置一次,但它的值在字段声明中是未知的。为此,我有:
public class MyClass {
private String field1 = null;
public void setField1(String value) {
if (field1 == null) {
field1 = value;
}
}
}
但是,我不会阻止用户多次拨打setField1
。这可能会导致用户试图设置它的混淆(不知道它已被设置在其他地方),然后用户会因为field1
没有给出他们设置的值而感到困惑 - 直到他们进入setField1
方法,看看发生了什么。
我不喜欢的另一个解决方案是使构造函数接受field1
的值,然后不提供setter。因为它使得类更难扩展,所以当需要多个String字段时 - 在这种方法中,构造函数需要接受一对String
作为参数,然后用户可能很容易被混淆/缺少参数。
显然将field1
设为final
也不会有效。
我应该怎样做才能防止上面提到的问题?
答案 0 :(得分:6)
在这种情况下的常见做法是抛出RuntimeException
。在你的情况下,IllegalStateException
最适合:
public void setField1(String value) {
if (field1 != null) {
throw new IllegalStateException("setField1 was already called");
}
field1 = Objects.requireNonNull(value);
}
另请注意,检查传递的字符串是否为空(我为此添加了Objects.requireNonNull
)。
您无法在编译时控制它,因为无法分析程序以确切地说明方法是否在没有实际运行程序的情况下调用一次或多次。
答案 1 :(得分:3)
对于这样的情况,您通常应该使用构建器模式:https://en.wikipedia.org/wiki/Builder_pattern
MyClass instance = (new MyClassBuilder())
.setField1(...)
.setField2(...)
.build();
您的构建器对象允许您设置所需的所有字段和选项,但它构建的MyClass实例不会。