空检查与可选是否存在检查 [英] Null check vs Optional is present check

查看:27
本文介绍了空检查与可选是否存在检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能解释一下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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆