JAVA8 的 Optional 是鸡肋
不使用 Optional,你得判空
使用 Optional,你还是得判空,只是换了一种形式
引入 Optional 降低代码可读性,代码变得丑陋
我在工作中从没见到有项目使用 Optional
除了使用 java stream 不得不用到 Optional
本质上 java 要在 null 上做优化只能通过底层语言设计上做改进(比如 Rust ),然而由于兼容性的需要,这条路已经走不通了
不使用 Optional,你得判空
使用 Optional,你还是得判空,只是换了一种形式
引入 Optional 降低代码可读性,代码变得丑陋
我在工作中从没见到有项目使用 Optional
除了使用 java stream 不得不用到 Optional
本质上 java 要在 null 上做优化只能通过底层语言设计上做改进(比如 Rust ),然而由于兼容性的需要,这条路已经走不通了
public static void main(String[] args) {
System.out.println(optional().isPresent());
}
使用的时候是否要对 `Optional` 判空呢?
Optional
.ofNullable(someVariable)
.map(this::findOtherObject)
.filter(this::isThisOtherObjectStale)
.map(this::convertToJson)
.map(String::trim)
.orElseThrow(() -> new RuntimeException(“something went horribly wrong.”));
代码来源: https://www.jdon.com/52008
用这个啊
如果你调用的 api 的编写人员不靠谱,那就让他别返回 Optional 了
仔细看看自己写的代码,照样都是 trade off
(点开看,原来不只是黑大 java,还要吹 rust,应该是最喜欢的编程语言评选又开始评选了
我觉得这个是函数式编程新进来的,不能拆开来看。
思想固化,从来没用过 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 ?
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());
}
“`
optional 真的很鸡肋
给我,我说鸡肋
不给,我说可以提供一个更好的
fp 这个东西怎么说呢,实际写起业务来也需要设计一番,难度不比设计类、接口这些低
如果自己设计、抽象的功底不够好还是简单 if else 走起吧,至少写出来的东西还能看懂
不,大约 5,6 年前,开始试用 Java8 的时候, 发现 Scala 没那么吸引人了。
我在 Spring 项目中第一次大规模使用 Java 8 的 Function/Consumer/Supplier 是应用 Spring Integrations 4 的 Java 8 DSL,当时它是单独的模块,现在是 Spring Integration 5 核心的一部分了。
https://spring.io/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
代码换个写法而已,不喜欢依然可以传统的方式。
Rust 和 Java 不兼容的地方是 borrow checker, 但是和你说的这个问题没有关系.
同理还有 Stream / Future 之类的和 async await 的关系.
Optional/Stream/Function/Labmda,Future 等,正经项目用过一次就习惯了,你再也不想回去了。
至于讨论“XXX 是鸡肋”这个问题本身就是鸡肋。
如果对于一种语言新语法,讨论如果使用,与其他语言对应的语法缺少什么,有什么优点,那还算一个帖子有点正面意义。
国内所有论坛的帖子,最多的就是在一些扯蛋的问题上撕逼。
编码调试阶段只有两个信息,错和没错。没有中间那档。
Optional 个人感觉很好用,刚开始可能不习惯,思维模式转变后发现真香
“但是这个只是警告,是非强制的。” 我就非要用 new 一个空对象出来,然后让他在某个地方空指针,反正编译过了就行。是不是一个意思?
你这样的心态,建议不要写 Java 了,去写某一个什么都给你安排的好好的语言。
另外,入参的问题,Optional 是协变的,所以不会用于入参……
自己没见过就说没用,别说自己会 Java 。
下面 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());
}
“`
API 设计本来就应该一层层约束的,如果调用别从的 API,返回 Optional,成为规约,而不应该返回是 Null 。
再说了,Spring 5 内部强制大量使用了 Asserts 工具类, Bean Validation (输入参数)和 JSR 305 (输入,结果等都可以约束) 来保证 API 稳定性。Spring Data 中 findByID 很早就改成返回 Optional, 用了几年,从来没见过返回此处 Optional==Null 的情况。如果有,请帖一些公开的开源的 API 看看。
不知道国内有多少用过 Null Object 模式。但我觉得这应该是一个最基本的问题,可以回避很多 Null 代码检测问题。
另外,像 Collection 类的使用,从我开始工作时,就看到一些相关的模式(或者叫实践)使用,比如:一个类中有一个 Collection field,应该初始化为一个 EmptyList/Set 等,有方法返回 Collection,永远保证不会返回 Null (没有结果以 Empty List/Set 代替)。
}
“`
以上每一个字段都有可能是空,那么你会先 5 个 if 语句来进行判断,optional 估计是解决这个问题的。