Java类,可用于表示null和不同的absent

时间:2014-05-01 22:23:02

标签: java guava

我想知道是否有一个现成的Java类可以与Guava的“可选”类似地使用,但是处理null并且不同。

我有一个用例需要传递一个带String值,null值或不存在的方法参数(不提供任何东西)。 Null是一个纯粹有效的值,具有特殊含义。

我尝试使用Guava的Optional,但发现它无法区分null和缺席。将null换成可选意味着缺席。

我想知道是否有可用于我的用例的现成Java实用程序:它可以携带值,空值或没有值(不存在)。

非常感谢

4 个答案:

答案 0 :(得分:1)

java语言可以做到:使用令牌对象代表"缺席"。

说它是一个字符串类型:

private static final String ABSENT = new String(""); // not interned

private String attribute = ABSENT;

public boolean attributeIsSet() {
    return attribute == ABSENT; // identity comparison
}

public String getAttribute() {
    if (attributeIsSet())
        return attribute;
    throw new IllegalStateException(); // or whatever
}

这允许null成为有效值。

答案 1 :(得分:1)

您应该使用Optional

Optional你知道有什么东西存在与否。通过返回... Optional将含义null添加到null

Optional<A> a = Optional.of(new A()); // We know that A is present.
Optional<B> b = Optional.absent();    // We know that B is absent.
Optional<C> c = null;                 // We don't know if C is present or absent.

使用null并不错:它容易出错。所以要小心,正确记录您想要做的事情以及应该如何解释null

答案 2 :(得分:-1)

字符串的空字符串(“”)是否与'无​​值'相同?显然这对数字不起作用,但你特别是在谈论一个字符串。

答案 3 :(得分:-1)

  

Null ......具有特殊意义。

每当你发现自己这样说时,a red flag你的设计应该重新思考,因为根据定义,null没有任何意义。让我们退一步看看你的要求(如果这是不准确的话,可以用更好的描述来更新问题):

  • 缺席:表示我们在这里无所事事
  • null:表示&#34;特殊值&#34;,例如DEFAULTFALLBACK,应特别处理
  • 价值:A&#34;正常&#34;值,包括可以直接处理的空字符串

这不是一个不常见的问题,(特别是在使用可空数据库列时,我认为你是这样)并且Optional可以非常成功地表示这一点,但我们需要更好地构建它。

虽然我们无法在数据库中避免使用NULL,但我们可以努力将其范围限制在围绕数据库访问行为的最小代码中,并将其暴露给它。如您所知,我们通过将可空字段转换为Optional来概念性地执行此操作。所以col VARCHAR NULL应该尽快转换为Java Optional<String> col

但现在我们需要代表缺席情况,例如当我们SELECT col FROM table LIMIT 1并且从我们的查询中得不到任何结果时。显然,这应该与我们返回NULL时的处理方式不同。

我们有几个选择,但它们都可以归结为以某种方式将我们的Optional<String>包装在另一层中。

在许多情况下,您只需使用List或其他Collection。通过传回一个非空集合,我们通常可以简单地处理缺少的情况,因为如果List为空,我们的代码将不会输入任何处理数据的循环。所以List<Optional<String>>是一种选择。

如果那是不可能的,并且你真的想要将行为限制为一对一,例如在上面的LIMIT 1示例中,只需将其包装在另一个Optional中,即Optional<Optional<String>>。这清楚地表达了缺少结果与以类型安全方式缺少值之间的差异。

更多的工作,但更好的是在自己的类中正确地表示这个结构(任何时候你在泛型中都有泛型,考虑创建一个合适的持有类),因为我们真正在谈论的是一个可选的数据,本身可能包含一段可选数据。

public class Row {
  private final Optional<String> col;
  public Row(@Nullable String col) {
    this.col = Optional.fromNullable(col);
  }
  public Optional<String> getCol() {
    return col;
  }
}

然后你传递Optional<Row>个对象,这些对象非常清楚地存在或不存在,并且包含结果或不包含结果。所有类型都安全,不需要null


tl; dr:这可以用Optional<Optional<String>>合理地表示,或者参见上面的其他建议。