我想知道是否有一个现成的Java类可以与Guava的“可选”类似地使用,但是处理null并且不同。
我有一个用例需要传递一个带String值,null值或不存在的方法参数(不提供任何东西)。 Null是一个纯粹有效的值,具有特殊含义。
我尝试使用Guava的Optional,但发现它无法区分null和缺席。将null换成可选意味着缺席。
我想知道是否有可用于我的用例的现成Java实用程序:它可以携带值,空值或没有值(不存在)。
非常感谢答案 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;,例如DEFAULT
或FALLBACK
,应特别处理这不是一个不常见的问题,(特别是在使用可空数据库列时,我认为你是这样)并且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>>
合理地表示,或者参见上面的其他建议。