27

如果您需要知道未设置布尔值的位置(例如,如果该未设置的值应该从父值继承),那么 Java 布尔原语(以及其他语言中的等价物)显然是不够的。

实现这一目标的最佳做法是什么?定义一个能够表达所有三种状态的新简单类或使用Java Boolean 类并使用null 表示未设置状态?

4

10 回答 10

51
Boolean a = true;
Boolean b = false;
Boolean c = null;

我会用那个。这是最直接的。

另一种方法是使用枚举。也许这样会更好更快,因为不需要拳击:

public enum ThreeState {
    TRUE,
    FALSE,
    TRALSE
};

第一个优点是您的类的用户不需要关心您的三态布尔值。他们仍然可以通过truefalse。如果你不喜欢null,因为它在这里很少说明它的含义,你仍然可以public static final Boolean tralse = null;在你的课堂上做一个。

于 2008-11-24T17:13:12.153 回答
17

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

作为奖励,您将获得所有这些地图消费方法。

于 2015-12-29T09:45:53.070 回答
10

虽然不是 Java 特定的,但我自己在这种情况下的偏好是定义一个 ThreeState 类或枚举并使用它——正如你提到的那样,一个 True、一个 False 和一个未定义(或默认值或未设置,作为您的域特定)术语规定)。感觉比用null.

于 2008-11-24T17:13:21.090 回答
9

@NullableBoolean得到我的投票。

于 2008-11-24T17:16:17.467 回答
6

使用空值来表示某事物的状态是糟糕的设计。它难以描述且难以维护。如果没有明确设置它,我宁愿拥有一个具有默认状态的 State 对象。例如:

if(state == null) {
    doSomething();
}

这并没有告诉我任何关于预期状态的信息。像这样的东西更清楚。

if(state.awaitingSet()) {
    doSomething();
}

更不用说可扩展了。当你需要第四个状态时会发生什么?

于 2008-11-24T17:17:46.730 回答
2

我会简单地使用值为 0,1,2 的 int(整数)并在程序中处理。

于 2017-09-04T15:47:57.787 回答
1

这取决于。在这里你提到如果它必须从父值继承它的值,它将是未设置的。你有某种数据层次结构吗?像这样的东西:

Parent a { 
    boolean val = true;
    boolean val2 = false; 
}
Child b {
    boolean val = false;
    //here val2 should be unset!
}

在这种情况下,如果可能的话,我会说简单地不要在 Child 中包含 val2,并且让您的查找逻辑使得如果找不到变量,它会在父母中搜索该值。

于 2008-11-24T17:16:45.920 回答
1

要添加到@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;
  }
}
于 2018-08-07T23:21:16.360 回答
-1

在父类中将布尔值初始化为 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";
}

确保断言已打开。断言仅适用于开发周期和测试周期,不适用于运行时异常。

于 2008-11-24T18:29:49.797 回答
-3

java.lang.Boolean 会为您执行此操作。有静态常量 Boolean.TRUE、Boolean.False。

私人布尔 myBoolean;

应该是您所需要的。注意 Boolean.TRUE 将通过等效测试,但不同于“true”(自动装箱为 TRUE)。

于 2008-11-24T17:15:13.553 回答