请教下 java8 的 Optional。。

2020-03-25 00:12:19 +08:00
 javaWeber

最近写了一堆空指针,打算改用下 java8 的 Optional 。。

请问下以下代码,怎么用 Optional 表示。

  1. 判断 A 是否为空,然后修改 B 或者执行其他逻辑。

想过用 if (isPresent())去判空,又觉得跟之前的 if 没什么区别。。

String str="123";
String result="abc";
if(str!=null){
	result+="def";
}

2.判断 A 是否为空,然后根据情况执行 if else 里面的逻辑。。

java9 有个 ifPresentOrElse(),不过项目里用的是 java8 。

String str="123";
String result="abc";
if(str!=null){
	result+="def";
}else {
    result+="ghi";
}
4467 次点击
所在节点    Java
31 条回复
javaWeber
2020-03-25 13:59:16 +08:00
@CommandZi 你这两个例子,不管 str 是不是 null,都不会空指针吧。
==============================================
我这里的例子写得不太准确,判断的是字符串,应该改成判断对象是否为空的。
```
if(对象!=空){

}
```
MakHoCheung
2020-03-25 14:07:25 +08:00
Optional 针对的是 str 。
这代码就算放到 kotlin 也要判 null,因为你的 str 是 String?类型
XiLemon
2020-03-25 16:50:55 +08:00
可以参考一下: http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy 关于 NULL 的处理建议
ica10888
2020-03-25 17:39:44 +08:00
其实这个是函数式编程的东西,相当于一个包装。不过一般情况下用来处理链式操作,如 getA().getB().getC() 的空指针异常,其实 kotlin 的语法糖要好看一些...
tachikomachann
2020-03-25 17:54:23 +08:00
我的理解是用 Optional 没办法减少判空操作,而是强制你必须判空。所以一旦用了 Optional,就不会无意识地写出 NPE 问题的代码。。
lyyhello
2020-03-25 18:57:11 +08:00
你看下 jdk8 用到 Optional 的地方的源码就知道了。如果有明确的返回,不用 Optional,如果因为各种原因(),结果不能保证一定为空,就用 Optional 返回。而且使用者不是简单的判断是否为空,而是和 Stream 紧密联系着用呢
Jrue0011
2020-03-26 10:46:30 +08:00
Optional 要用上 map/flatMap 、filter 。一般应该是一段代码调用多个方法,每个方法入参都是上个方法返回值或返回值部分,Optional 的 map/flatMap 可以避免对每个返回值判断 null,如果对返回值的判断不仅仅是否 null 的话,可以用 filter 判断。

比如这样。。。

Optional.of(userId).map(userDao::getPhone).filter(phoneService::isChinaMobile).ifPresent(smsService::sendMsg);
Optional.of(userId).map(userDao::getPhone).map(phoneBook::getContactListByPhone).orElseGet(Collections::emptyList);
或者如果有需要抛业务异常,也可以用 orElseThrow
CommandZi
2020-03-26 11:15:28 +08:00
@javaWeber Optional 设计是用来减少空指针异常,不是减少 if(对象!=空)这类操作的。你 if 后续代码都没调用对象,说明这只是你程序的固定逻辑而已,不管对象用不用 optional,都是要判断的。
CommandZi
2020-03-26 11:17:07 +08:00
@CommandZi 当然这是我使用 Swift 当中的 Optional 的经验,Java 的没有了解。
MotherShip
2020-04-01 21:43:55 +08:00
手头上用的比较优雅的玩法大概是,Repository 层返回一个 Optional 对象,为空则直接一路把异常抛到 Controller 层然后统一处理:

```java
String a = Optional.ofNullable("a").orElseThrow(()->{throw new RuntimeException();});
```
至于你这两个例子。。确实用不用没啥区别
facelezz
2020-08-13 10:06:24 +08:00
楼上回答了那么多,其实 guava 文档里就有解释。
Besides the increase in readability that comes from giving null a name (增加了可读性,isPresent()比 if xxx!=null 可读性好)
the biggest advantage of Optional is its idiot-proof-ness.It forces you to actively think about the absent case if you want your program to compile at all, since you have to actively unwrap the Optional and address that case (使用了 option 后,强迫你思考不存在的情况,避免忘记)

This is especially relevant when you're returning values that may or may not be "present." You (and others) are far more likely to forget that other.method(a, b) could return a null value than you're likely to forget that a could be null when you're implementing other.method. Returning Optional makes it impossible for callers to forget that case, since they have to unwrap the object themselves for their code to compile.

(对设计的优化,如果你的方法返回值可能存在也可能不存在,就尽量返回 optional,这样别人用你的方法就知道需要判断)
至于 orElse 这种类型操作,我自己理解的是 4 楼那样,此外,optional 并不是用来简化流程,只是一种设计,让人记住去处理 null

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/655876

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX