Java 定义真、假、未设置状态的最佳方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/314800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:03:17  来源:igfitidea点击:

Best way to define true, false, unset state

javaboolean

提问by Tom Martin

If you have a situation where you need to know where a boolean value wasn't set (for example if that unset value should inherit from a parent value) the Java boolean primitive (and the equivalent in other languages) is clearly not adequate.

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

What's the best practice to achieve this? Define a new simple class that is capable of expressing all three states or use the Java Boolean class and use null to indicate the unset state?

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

采纳答案by Johannes Schaub - litb

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

I would use that. It's the most straight-forward.

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

Another way is to use an enumeration. Maybe that's even better and faster, since no boxing is required:

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

public enum ThreeState {
    TRUE,
    FALSE,
    TRALSE
};

There is the advantage of the first that users of your class doesn't need to care about your three-state boolean. They can still pass trueand false. If you don't like the null, since it's telling rather little about its meaning here, you can still make a public static final Boolean tralse = null;in your class.

第一个优点是您班级的用户不需要关心您的三态布尔值。他们仍然可以通过truefalse。如果你不喜欢null,因为它在这里几乎没有说明它的含义,你仍然可以public static final Boolean tralse = null;在你的班级中制作 a 。

回答by John Rudy

Although not Java-specific, my own preference in this scenario is to define a ThreeState class or enumeration and use it -- just as you mentioned, a True, a False and an Undefined (or Default, or Unset, as your domain-specific terminology dictates). It feels better, more natural and more self-documenting than representing unset/undefined with null.

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

回答by Steve B.

java.lang.Boolean does this for you. There are static constants Boolean.TRUE, Boolean.False.

java.lang.Boolean 为你做这件事。有静态常量Boolean.TRUE、Boolean.False。

private Boolean myBoolean;

私人布尔 myBoolean;

should be all you need.Note that Boolean.TRUE will pass an equivalence test but is distinct from "true" (which gets autoboxed to TRUE).

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

回答by Chris Simpson

The @Nullable Booleangets my vote.

@NullableBoolean得到了我的投票。

回答by Claudiu

It depends. Here you mention it would be unset if it has to inherit its value from a parent value. Do you have some kind of data hierarchy? Something like this:

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

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

In this case, if it's possible, I'd say simply don't include val2 in the Child, and have your lookup logic be such that if it doesn't find the variable, it searches the parents for the value.

在这种情况下,如果可能的话,我只想说不要在 Child 中包含 val2,并且让您的查找逻辑是这样的,如果它没有找到变量,它会在父项中搜索该值。

回答by Hates_

Using nulls to represent the state of something is poor design. It's undescriptive and hard to maintain. I would rather have a State object with a default state if nothing has been explicitly set on it. For example:

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

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

This doesn't tell me anything about what the expected state is. Something more like this makes it more clear.

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

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

Not to mention extensible. What happens when you need a fourthstate?

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

回答by WolfmanDragon

In the Parent class initiate the boolean to null and in the child class build a method to check to see if the boolean has been set

在父类中将布尔值初始化为 null 并在子类中构建一个方法来检查是否已设置布尔值

in Parent class

在父类

private Boolean a = null;

public void setA(Boolean a) {
    this.a = a;
}


public Boolean getA() {
    return a;
}

In the Child Class

在儿童班

if (a == true)
{
dothis;
}
else if (a == false)
{
dothat;
}
else
{
assert false : "Boolean a has not been set";
}

Make sure that assertions are turned on. Assertions are only for the development cycle and test cycle, they are not for runtime exceptions.

确保断言已打开。断言只针对开发周期和测试周期,不针对运行时异常。

回答by voho

In Java 8, there is also the Optionaloption:

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

As a bonus, you will get all those mapand consumemethods.

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

回答by Suriya

I would simply use a int (integer) with values 0,1,2 and handle within program.

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

回答by John Coker

To add to @voho, Optional also plays nicely with lambda, making a potentially cleaner structure:

要添加到@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);
  }
}

However, it's still not obviously that much better than Boolean and a null check:

但是,它显然仍然没有比 Boolean 和 null 检查好多少:

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;
  }
}