java 空检查与可选是否存在检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40778248/
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-11-03 05:28:02  来源:igfitidea点击:

Null check vs Optional is present check

javafunctional-programmingjava-8optional

提问by Faiz Halde

Can someone explain how Optionalhelps us avoid NullPointerException?

有人能解释一下如何Optional帮助我们避免NullPointerException吗?

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

Isn't this code prone to NullPointerExceptiontoo? If so, then why is this code preferred over

这段代码不是NullPointerException也很容易吗?如果是这样,那么为什么此代码优于

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

What possible benefit does Optionalprovide other than the fact that it helps us in knowing whether a function actually had a return value or not

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

回答by Stuart Marks

Let's say you want to get a string returned by a function, convert it to upper case, and then print it out. If you have:

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

String someFunc() { ... }

You might be tempted to write:

你可能会想写:

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

Of course, this throws NullPointerExceptionif someFuncreturns null. Instead, suppose we have this:

当然,这会抛出NullPointerExceptionifsomeFunc返回null。相反,假设我们有这个:

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

Then

然后

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

won't work, since Optionaldoesn't have a toUpperCasemethod. At this point -- hopefully -- you'll be confronted with an Optional, which should make you think about the case of the Optionalbeing empty. This helps avoid NPEs, but probably only somewhat.

不会工作,因为Optional没有toUpperCase方法。在这一点上——希望——你会遇到一个Optional,它应该让你考虑Optional空的情况。这有助于避免 NPE,但可能只是在某种程度上。

Now you might be focusing on how to get the value out of the Optional, and you might forget about the empty case. Ah, there's a getmethod:

现在您可能专注于如何从 中获取值Optional,而您可能会忘记空情况。啊,有一个get方法:

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

This brings back the same problem as NPE, except that the exception is NoSuchElementExceptioninstead. So if you blindly call geton an Optional, it really is pretty much the same thing as calling a method on a reference without checking whether it's null.

这带来了与 NPE 相同的问题,除了例外NoSuchElementException。因此,如果你盲目地调用getan Optional,它实际上与在引用上调用方法而不检查它是否为空几乎是一样的。

(For this reason, Brian Goetzconsiders Optional.getto be the biggest mistake in Java 8. See his interview with Angelika Langer JAX 2015 Fragen und Antworten zu Java 8at about 16 minutes in. I'm not sure it's the biggest, but it is a mistake. People just don't expect getto throw an exception.)

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

If you're diligent about checking for null references or empty optionals, then

如果您勤于检查空引用或空选项,那么

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

is hardly any better than the old

几乎没有比旧的好

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

The realadvantage of Optionalis that it's a library class that has a fairly rich API for dealing with the empty case in a safe way. It's often possible to process the value that might be contained within an Optionalby chaining a couple method calls to the method that returned the Optionalin the first place. For example, we could rewrite the sample above as follows:

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

someFunc().map(String::toUpperCase)
          .ifPresent(System.out::println);