如果您需要知道未设置布尔值的位置(例如,如果该未设置的值应该从父值继承),那么 Java 布尔原语(以及其他语言中的等价物)显然是不够的。
实现这一目标的最佳做法是什么?定义一个能够表达所有三种状态的新简单类或使用Java Boolean 类并使用null 表示未设置状态?
Boolean a = true;
Boolean b = false;
Boolean c = null;
我会用那个。这是最直接的。
另一种方法是使用枚举。也许这样会更好更快,因为不需要拳击:
public enum ThreeState {
TRUE,
FALSE,
TRALSE
};
第一个优点是您的类的用户不需要关心您的三态布尔值。他们仍然可以通过true
和false
。如果你不喜欢null
,因为它在这里很少说明它的含义,你仍然可以public static final Boolean tralse = null;
在你的课堂上做一个。
在 Java 8 中,还有Optional选项:
public static final Optional<Boolean> TRI_TRUE = Optional.of(true);
public static final Optional<Boolean> TRI_FALSE = Optional.of(false);
public static final Optional<Boolean> TRI_UNKNOWN = Optional.empty();
作为奖励,您将获得所有这些地图和消费方法。
虽然不是 Java 特定的,但我自己在这种情况下的偏好是定义一个 ThreeState 类或枚举并使用它——正如你提到的那样,一个 True、一个 False 和一个未定义(或默认值或未设置,作为您的域特定)术语规定)。感觉比用null
.
@NullableBoolean
得到我的投票。
使用空值来表示某事物的状态是糟糕的设计。它难以描述且难以维护。如果没有明确设置它,我宁愿拥有一个具有默认状态的 State 对象。例如:
if(state == null) {
doSomething();
}
这并没有告诉我任何关于预期状态的信息。像这样的东西更清楚。
if(state.awaitingSet()) {
doSomething();
}
更不用说可扩展了。当你需要第四个状态时会发生什么?
我会简单地使用值为 0,1,2 的 int(整数)并在程序中处理。
这取决于。在这里你提到如果它必须从父值继承它的值,它将是未设置的。你有某种数据层次结构吗?像这样的东西:
Parent a {
boolean val = true;
boolean val2 = false;
}
Child b {
boolean val = false;
//here val2 should be unset!
}
在这种情况下,如果可能的话,我会说简单地不要在 Child 中包含 val2,并且让您的查找逻辑使得如果找不到变量,它会在父母中搜索该值。
要添加到@voho,Optional 还可以很好地与 lambda 配合使用,从而形成一个可能更清洁的结构:
public class Node {
private Node parent;
private Optional<Boolean> something = Optional.empty();
public boolean isSomething() {
return something.orElseGet(() -> {
if (parent != null)
return parent.isSomething();
return false;
});
}
public void setSomething(boolean v) {
this.something = Optional.of(v);
}
}
但是,它显然仍然没有比布尔值和空值检查好多少:
public class Node {
private Node parent;
private Boolean something;
public boolean isSomething() {
if (something != null)
return something;
if (parent != null)
return parent.isSomething();
return false;
}
public void setSomething(boolean v) {
this.something = v;
}
}
在父类中将布尔值初始化为 null 并在子类中构建一个方法来检查布尔值是否已设置
在父类
private Boolean a = null;
public void setA(Boolean a) {
this.a = a;
}
public Boolean getA() {
return a;
}
在儿童班
if (a == true)
{
dothis;
}
else if (a == false)
{
dothat;
}
else
{
assert false : "Boolean a has not been set";
}
确保断言已打开。断言仅适用于开发周期和测试周期,不适用于运行时异常。
java.lang.Boolean 会为您执行此操作。有静态常量 Boolean.TRUE、Boolean.False。
私人布尔 myBoolean;
应该是您所需要的。注意 Boolean.TRUE 将通过等效测试,但不同于“true”(自动装箱为 TRUE)。