JAVA8 的 Optional 是鸡肋

2021-01-25 15:00:29 +08:00
 mightofcode
对于处理 NPE 问题基本没有帮助

不使用 Optional,你得判空
使用 Optional,你还是得判空,只是换了一种形式
引入 Optional 降低代码可读性,代码变得丑陋

我在工作中从没见到有项目使用 Optional
除了使用 java stream 不得不用到 Optional

本质上 java 要在 null 上做优化只能通过底层语言设计上做改进(比如 Rust ),然而由于兼容性的需要,这条路已经走不通了
13120 次点击
所在节点    Java
118 条回复
PiersSoCool
2021-01-26 10:25:38 +08:00
如 a.b.c.d.e.f 的时候喜欢用 Optional
要是 a 我喜欢用 null == a
怎么方便怎么来
CosimoZi
2021-01-26 10:31:30 +08:00
球球你们学点 plt 吧
qiyuey
2021-01-26 10:59:52 +08:00
不如 Kotlin 彻底一些
casillasyi
2021-01-26 11:00:20 +08:00
@cheng6563 能让 optional 为 null 的,跟写 if (true) 也没区别
unco020511
2021-01-26 11:16:59 +08:00
kotlin 的好用
yl666
2021-01-26 11:32:01 +08:00
我有个 String 类型的数据,本来想通过用 Optional.ofNullable 来判断是否为空的,结果看了下源码发现它是用 xx == null 来判断的,最后还是用 if 判断吧,其实 Optional 挺好用的,只不过某些场景不太适合
zhuangzhuang1988
2021-01-26 11:35:58 +08:00
@lululau 可读性确实低
而且性能差, 而且可调试不好
hantsy
2021-01-26 11:53:15 +08:00
@casillasyi 写法差别很大。
Optional 流式操作都是假定它不是 Null,如果数据流遇到 Null 的情况走 Else 路线,这和 Scala 中 OPTION,SOME,NULL 类似,Java 8 中要处理 if a= null 情况使用 Optinal 非常容易,代码看起来舒服得多, 在实际项目非常实用。

下面 Spring 5.2 加入 MVC 加入 Funtional 编程的例子,传统的 Controller 一样可以用。

https://github.com/hantsy/spring-webmvc-functional-sample/blob/master/java/src/main/java/com/example/demo/DemoApplication.java#L77-L85

```java
public ServerResponse get(ServerRequest req) {
return this.posts.findById(Long.valueOf(req.pathVariable("id")))
.map(post -> ok().body(post))
.orElse(notFound().build());
}
```
hantsy
2021-01-26 11:55:54 +08:00
@yl666 所有的判断 Null 的情况都是可以用 Optional, 更方便。 你觉得不方便或者不适合,只是思想上还没接受 Stream 方式,缺少 Stream API 使用实践。
casillasyi
2021-01-26 11:58:59 +08:00
@hantsy 我觉得他们认为的 optional 本身是 null 的情况是这个对象是 null,而不是 value 为 null
AxEqaq
2021-01-26 12:15:10 +08:00
用 guava 的 cache 还是需要用到 optional 判空的
hantsy
2021-01-26 12:19:25 +08:00
@casillasyi

API 设计本来就应该一层层约束的,如果调用别从的 API,返回 Optional,成为规约,而不应该返回是 Null 。

再说了,Spring 5 内部强制大量使用了 Asserts 工具类, Bean Validation (输入参数)和 JSR 305 (输入,结果等都可以约束) 来保证 API 稳定性。Spring Data 中 findByID 很早就改成返回 Optional, 用了几年,从来没见过返回此处 Optional==Null 的情况。如果有,请帖一些公开的开源的 API 看看。
casillasyi
2021-01-26 12:30:43 +08:00
@hantsy 问他们啊。。。
oneisall8955
2021-01-26 12:33:42 +08:00
一开始我觉得鸡肋,后来发现是自己姿势不对(=_=)
oneisall8955
2021-01-26 12:41:47 +08:00
@huifer 接口定义返回 Optional,默认就是不会返回 null,调用者不用判断是否是 null,如果返回 null,把锅甩给开发这个接口的辣鸡开发
oneisall8955
2021-01-26 12:43:45 +08:00
@hantsy 赞同,楼上说需要 optional == null 都是没理解透彻 optional 的精髓
hantsy
2021-01-26 13:14:56 +08:00
@oneisall8955 这个情况在国内可能太多了,因为之前我在上海两个创业项目的经历,现在的年轻开发人员基本敷衍做事的太多,很多基本的代码约束都做不到,要费很多唇舌去要求。

不知道国内有多少用过 Null Object 模式。但我觉得这应该是一个最基本的问题,可以回避很多 Null 代码检测问题。

另外,像 Collection 类的使用,从我开始工作时,就看到一些相关的模式(或者叫实践)使用,比如:一个类中有一个 Collection field,应该初始化为一个 EmptyList/Set 等,有方法返回 Collection,永远保证不会返回 Null (没有结果以 Empty List/Set 代替)。
nnnToTnnn
2021-01-26 13:18:06 +08:00
Java 基本上好几年没写了,我的 jdk 8 出来的时候, 我依稀记得 optional 是为了解决 a?.b() 的问题,但是由于 Java 是面向对象的语言,这个思想还没怎么转换过来。 所以目前的 optional 应该是为了解决 Stream API 中 a?.b() 的问题,而不是单纯的空指针。
nnnToTnnn
2021-01-26 13:20:56 +08:00
例子 这是一个 List 结构
```
{
user: {
name: {
name: {
name: {
key: '1'
}
}
}
}

}

```

以上每一个字段都有可能是空,那么你会先 5 个 if 语句来进行判断,optional 估计是解决这个问题的。
jewer3330
2021-01-26 13:31:54 +08:00
吃瓜群众

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

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

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

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

© 2021 V2EX