空检查与可选是否存在检查 [英] Null check vs Optional is present check
问题描述
谁能解释一下Optional
如何帮助我们避免NullPointerException
?
Can someone explain how Optional
helps us avoid NullPointerException
?
Optional<String> op = someFunc()
if(op.isPresent()) {
op.get();
}
String possibleNull = op.get();
这段代码是不是也容易出现NullPointerException
?如果是这样,那么为什么此代码优于
Isn't this code prone to NullPointerException
too? If so, then why is this code preferred over
String op = someFunc()
if(op != null) {
op.get();
}
String possibleNull = op;
Optional
除了帮助我们了解函数是否真的有返回值这一事实之外,还有什么可能的好处
What possible benefit does Optional
provide other than the fact that it helps us in knowing whether a function actually had a return value or not
推荐答案
假设你想得到一个函数返回的字符串,将其转换为大写,然后打印出来.如果您有:
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() { ... }
你可能想写:
System.out.println(someFunc().toUpperCase());
当然,如果 someFunc
返回 null
,这将抛出 NullPointerException
.相反,假设我们有这个:
Of course, this throws NullPointerException
if someFunc
returns null
. Instead, suppose we have this:
Optional<String> someFunc() { ... }
然后
System.out.println(someFunc().toUpperCase());
不起作用,因为 Optional
没有 toUpperCase
方法.在这一点上——希望——你会遇到一个 Optional
,它应该让你考虑 Optional
为空的情况.这有助于避免 NPE,但可能只是在一定程度上避免.
won't work, since Optional
doesn't have a toUpperCase
method. At this point -- hopefully -- you'll be confronted with an Optional
, which should make you think about the case of the Optional
being empty. This helps avoid NPEs, but probably only somewhat.
现在您可能专注于如何从 Optional
中获取值,而您可能忘记了空情况.啊,有一个 get
方法:
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 get
method:
System.out.println(someFunc().get().toUpperCase());
这带来了与 NPE 相同的问题,只是例外是 NoSuchElementException
.因此,如果您盲目地在 Optional
上调用 get
,它实际上与在引用上调用方法而不检查它是否为 null 几乎相同.
This brings back the same problem as NPE, except that the exception is NoSuchElementException
instead. So if you blindly call get
on an Optional
, it really is pretty much the same thing as calling a method on a reference without checking whether it's null.
(因此,Brian Goetz 认为 Optional.get
是Java 8 中最大的错误.参见他对 Angelika Langer 的采访 JAX 2015 Fragen und Antworten zu Java 8 大约 16 分钟.我不确定这是最大的,但这是一个错误.人们只是不期望 get
抛出异常.)
(For this reason, Brian Goetz considers Optional.get
to be the biggest mistake in Java 8. See his interview with Angelika Langer JAX 2015 Fragen und Antworten zu Java 8 at about 16 minutes in. I'm not sure it's the biggest, but it is a mistake. People just don't expect get
to throw an exception.)
如果您勤于检查空引用或空选项,那么
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());
}
几乎没有比旧的好
String s = someFunc();
if (s != null) {
System.out.println(s.toUpperCase());
}
Optional
的真正优势在于,它是一个库类,具有相当丰富的 API,可以安全地处理空情况.通常可以通过将几个方法调用链接到首先返回 Optional
的方法来处理可能包含在 Optional
中的值.例如,我们可以将上面的示例重写如下:
The real advantage of Optional
is 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 Optional
by chaining a couple method calls to the method that returned the Optional
in the first place. For example, we could rewrite the sample above as follows:
someFunc().map(String::toUpperCase)
.ifPresent(System.out::println);
这篇关于空检查与可选是否存在检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!