如何允许在 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 实例不能。
我需要在 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 实例不能。