当前位置: 首页 > 知识库问答 >
问题:

空检查vs可选存在检查

方和豫
2023-03-14

有人能解释一下可选如何帮助我们避免空点异常

Optional<String> op = someFunc()
if(op.isPresent()) {
   op.get();
}
String possibleNull = op.get();

这段代码不是也容易出现NullPointerException吗?如果是这样的话,那么为什么这个代码比

String op = someFunc()
if(op != null) {
   op.get();
}
String possibleNull = op;

Optional除了帮助我们了解函数是否实际具有返回值之外,还有什么可能的好处

共有1个答案

楚举
2023-03-14

假设您希望获取函数返回的字符串,将其转换为大写,然后将其打印出来。如果您有:

String someFunc() { ... }

你可能会想写:

System.out.println(someFunc().toUpperCase());

当然,如果someFunc返回null,则会抛出NullPointerException。相反,假设我们有:

Optional<String> someFunc() { ... }

然后呢

System.out.println(someFunc().toUpperCase());

将不工作,因为可选没有一个toUpperCase方法。在这一点上--希望--您将面临一个可选的,这应该会让您考虑可选的是空的情况。这有助于避免NPE,但可能只是在一定程度上。

现在,您可能将重点放在如何从可选中获取值上,而您可能会忘记空的大小写。啊,有一个get方法:

System.out.println(someFunc().get().toUpperCase());

这带来了与NPE相同的问题,除了异常是NoSuchElementExc0019。因此,如果您盲目地在一个可选的上调用get,这实际上与在引用上调用一个方法而不检查它是否为空几乎是一样的。

(因此,Brian Goetz认为是可选的。get是Java 8中最大的错误。请看他在大约16分钟后对Angelika Langer JAX 2015 Fragen und Antworten zu Java 8的采访。我不确定这是最大的错误,但这是一个错误。人们只是不希望get抛出异常。)

如果你努力检查空引用或空选项,那么

Optional<String> os = someFunc();
if (os.isPresent()) {
    System.out.println(os.get().toUpperCase());
}

几乎没有比旧的更好的了

String s = someFunc();
if (s != null) {
    System.out.println(s.toUpperCase());
}

Optional的真正优势在于,它是一个库类,具有相当丰富的API,用于以html" target="_blank">安全的方式处理空案例。通常可以通过将几个方法调用链接到首先返回Optional的方法来处理Optional中可能包含的值。例如,我们可以将上面的示例重写如下:

someFunc().map(String::toUpperCase)
          .ifPresent(System.out::println);
 类似资料:
  • 有人能解释一下<code>是可选的</code>如何帮助我们避免<code>NullPointerException</code>吗? 这段代码不是也容易出现<code>NullPointerException</code>吗?如果是这样的话,那么为什么这个代码比其他代码更受欢迎 除了帮助我们了解函数是否实际具有返回值之外,还提供了什么可能的好处

  • 问题内容: 在Objective-C中,当我有一个数组时 我想检查它是否不为空,我总是这样做: 这样一来,无需检查是否会因为这种情况将导致代码陷入错误,并且非空数组也会这样做。 但是,在Swift中,我偶然发现了一个可选数组: 而且我无法确定要使用哪种条件。我有一些选择,例如: 选项A:在相同条件下检查非用例和空用例: 选项B: 使用解除绑定数组: 选项C: 使用Swift提供的合并运算符: 我不

  • 我喜欢的,我觉得很酷的东西 有人能告诉我我没意见吗?也许很酷,但成本很高?我不知道.多谢.

  • 我正在开发一个使用返回的方法的程序,我需要迭代它并创建一个新对象。我该怎么做? 我对Java可选选项的理解是减少检查,但如果没有检查,我仍然无法做到这一点。使用或并拥有简洁的代码,有没有更好的解决方案?

  • 当我想检查可选布尔值是否为真时,这样做行不通: 它会导致以下错误: 可选类型“@IvalueBool?”不能用作布尔值;测试'!=而不是零 我不想检查nil;我想检查返回的值是否为真。 如果布尔值==true,我是否总是必须执行