JAVA8 的 Optional 是鸡肋

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

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

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

本质上 java 要在 null 上做优化只能通过底层语言设计上做改进(比如 Rust ),然而由于兼容性的需要,这条路已经走不通了
12575 次点击
所在节点    Java
118 条回复
Takamine
2021-01-25 16:09:07 +08:00
比如*。

我觉得这个是函数式编程新进来的,不能拆开来看。
lemon94
2021-01-25 16:18:31 +08:00
swift 也有 optional,是繁琐了点,但解决 npe 问题还算有成效。
hantsy
2021-01-25 16:21:18 +08:00
Optional 太常用了。

思想固化,从来没用过 Java 8 的人才会去判断是不是 NULL,把好好的代码打回 Java 8 以前。

Optional 在 Java 8 改进了很多,和 Stream 一样,用于 Pipeline 类似操作,很方便。

https://github.com/hantsy/spring-webmvc-jwt-sample/blob/master/src/main/java/com/example/demo/DemoApplication.java#L34-L45

```java

@Bean
public AuditorAware<User> auditor() {
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(User.class::cast);
}
```

再说了以 Spring 5 为基础,核心代码还有其 Spring 生态(比如 Spring Data ) API 都是对 Java 8 API 优化,Optional 在 Spring 中已经是随处可见,难道还没升级 Spring 5 ?
assiadamo
2021-01-25 16:22:37 +08:00
jdk 的 Optional 无法序列化且对 GC 有压力,有个好用的库叫 vavr 可以替代
assiadamo
2021-01-25 16:23:21 +08:00
比如 netty 就不用 Optional
hantsy
2021-01-25 16:27:03 +08:00
如果用过 Spring WebFlux ( ReactiveStreams API )就更不用说了,流式操作是必须的。

https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/main/java/com/example/demo/config/MongoConfig.java#L19-L28

```java
@Bean
ReactiveAuditorAware<Username> reactiveAuditorAware() {
return () -> ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(UserDetails.class::cast)
.map(UserDetails::getUsername)
.map(Username::new)
.switchIfEmpty(Mono.empty());
}
```
EscYezi
2021-01-25 16:29:53 +08:00
@tamer #15 还得看实际业务,之前确实用到过这种写法
Leviathann
2021-01-25 16:40:18 +08:00
有时候把它当成三目用,至少比裸写三目漂亮
chenfcheng
2021-01-25 17:38:35 +08:00
Optional.ofNullable(o1.getx().getxx().getXXX()).orElse() 这时候最有用 多层嵌套情况下 可直接设置默认值 多次判断是否为空
mightofcode
2021-01-25 17:43:20 +08:00
@yuanxiaosong 这就是我说的 stream 的场景
mightofcode
2021-01-25 17:45:33 +08:00
@Jooooooooo 不用 optional 抛出 NPE,用 optional,抛 NoSuchElementException

optional 真的很鸡肋
mightofcode
2021-01-25 17:46:37 +08:00
@arloor

给我,我说鸡肋
不给,我说可以提供一个更好的
zhuangzhuang1988
2021-01-25 17:47:14 +08:00
✓ 很多 fp 就是放屁
shyling
2021-01-25 17:47:28 +08:00
黑 java 可以,但 rust 不是一样的操作?
mightofcode
2021-01-25 17:50:11 +08:00
@Jirajine optional 做不到强制检查 null,你一样可以选择直接调用 get,然后抛出 NoSuchElementException
mightofcode
2021-01-25 17:50:55 +08:00
@shyling rust 不一样,rust 如果声明不返回 null,那就绝对不会返回 null
1011
2021-01-25 17:51:53 +08:00
@hantsy
@yuanxiaosong

fp 这个东西怎么说呢,实际写起业务来也需要设计一番,难度不比设计类、接口这些低
如果自己设计、抽象的功底不够好还是简单 if else 走起吧,至少写出来的东西还能看懂
mightofcode
2021-01-25 17:51:55 +08:00
@LGA1150 警告不是 error,就有可能被无视
mightofcode
2021-01-25 17:52:39 +08:00
@sampeng optional 消灭不了空指针,你如果能用 optional 消灭空指针,发出来大家学习下
yazinnnn
2021-01-25 17:59:10 +08:00
不过说实话,单拿 optional 出来做 fp 确实没啥用,java 的函数式还是太弱了

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

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

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

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

© 2021 V2EX