假设您要获取函数返回的字符串,将其转换为大写,然后将其打印出来。如果您有:
String someFunc() { ... }
你可能会想写:
System.out.println(someFunc().toUpperCase());
当然,如果返回,这将抛出。相反,假设我们有这个:NullPointerException
someFunc
null
Optional<String> someFunc() { ... }
然后
System.out.println(someFunc().toUpperCase());
不起作用,因为没有方法。在这一点上 - 希望 - 你将面临一个,这应该让你想到空的情况。这有助于避免NPE,但可能只是在一定程度上。Optional
toUpperCase
Optional
Optional
现在,您可能正在关注如何从 中获取值,而您可能会忘记空大小写。啊,有一种方法:Optional
get
System.out.println(someFunc().get().toUpperCase());
这又带来了与 NPE 相同的问题,只是例外是相反的。因此,如果您盲目地调用 一个 ,它实际上与在不检查它是否为空的情况下在引用上调用方法几乎是一回事。NoSuchElementException
get
Optional
(出于这个原因,Brian Goetz认为这是Java 8中最大的错误。查看他对Angelika Langer JAX 2015 Fragen und Antworten zu Java 8的采访,大约16分钟。我不确定这是最大的,但这是一个错误。人们只是不希望抛出异常。Optional.get
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());
}
真正的优点是它是一个库类,具有相当丰富的API,用于以安全的方式处理空案例。通常可以通过将几个方法调用链接到首先返回的方法来处理可能包含的值。例如,我们可以重写上面的示例,如下所示:Optional
Optional
Optional
someFunc().map(String::toUpperCase)
.ifPresent(System.out::println);