你随便 Google 一下就有了哇,你这里更好是用 pData.ifPresent()

String username = Optional.ofNullable(people).ifPresent(People::getName).orElse(null);

需要从一个对象连续获取值的时候String username = Optional.ofNullable(people).map(People::getName).orElse(null);

String username = Optional.ofNullable(people).map(People::getName).orElse(null);2# ifPresent void

chaining

太优雅了

链式的时候可以用, 简单判断一个字段是否有值的时候, 真不如 if (xxx != null )

确实好一点,那大哥,假如 People 对象里面还有一个 Job 对象, 我想获取里面的 jobName, 这种写法可以吗

因为我们项目有时候返回几十个字段,以前都是 String name = people == null ? "" : people.getName() 这样

  1. 可以在返回值里使用 optional ,提醒调用方这里返回的值可能为空,包装成 optional 对象就是强制要求调用者对空值情况进行判断处理。2. 连续取值。比如你接到一个层级很复杂的 json 对象,将其转换成 map 结构,一层一层的 get 需要判断 null ,用 Optional 的话,就算是内嵌深度是 10 层,也能用一行 optional 解决,避免出现嵌套 10 层 if-else 判断

    链式调用吗

    如果 api 这么设计好像也挺清晰的

    这两点都还挺有用的,学到了

    好哒

    String jobName = Optional.ofNullable(people).map(People::getJob).map(Job::getJobName).orElse(null);这样写也可以,嵌套对象取值还挺方便的

总结一下就是#10 楼大哥说的优势, 感谢大家的回复

可以减少代码行数,又不损失可读性的时候

在其他语法丰富的语言里就是people?.job?.jobName??””在 Java 里就只能是这样了

Groovy!

因为 null 指针的引入本身就是个历史错误。用 Optional 类型改正了这个历史错误。虽然在一些情况下,和写检查 null 一样。但是引入了 Optional 类型相当于强制你做检查了。

Swift !

dart 里好像也有这个

惊到我了,以前看到 Java 新增 Optional Value 的时候我还想越来越现代化了,没想到这个老太太的裹脚布果然没让我失望

说实话,没多大用,不如 和
kotlin:就这?

kotlin 更优雅 val jobName = people?.job?.jobName ?: null

基本不用,这就是个 nullability 的残废实现,慢慢等 mail.openjdk.org/pipermail/valhalla-spec-experts/2023-May/002276.html 吧

一般是用 orElse 、flatMap 来串接不同的处理过程的吧。if isPresent 这个写法太命令式了。直接 get 的话说实话不如不要用 Optional 。当然 Optional 确实很难用就是了。

烂设计,没有必要用。

kotlin: val jobName = people?.job?.jobName ?: nulljs/ts: const jobName = people?.job?.jobName?.[0] ?? nullc#: var jobName = people?.job?.jobName?[0] ?? nullSwift: let value = obj?.nestedObj?.propertydart: var jobName = people?.job?.jobName ?: null但是肯定有人觉得 Optional 比上面更好用,毕竟祖宗之法不可变

复制一点实际业务代码var fileName = file.getName();var fileInfo = new FileInfo();SessionContext.userName().ifPresent(fileInfo::setUserName);MediaTypeFactory.getMediaType(fileName).map(MediaType::toString).ifPresent(fileInfo::setContentType);

有时候??多了有点增加阅读难度,当然也是因为用的不多不够熟悉 kt 。.let 复杂点 ide 提示的自己都看不懂

不是拿来单独取代 if 判断的是拿来写 lambda 的

我还记得以前有人笑过 Optional ,大概是说 Java 的 Maybe 居然有三种状态:Just ,Noting 和 NULL 。

null 就是个阉割版的 Optional ,而且明显更祖宗。Optional 本身本来也不是太大的问题(起码回避起来比起无处不在的 null 来说容易多了),问题是 null 这祖宗干不掉,又另外加上 Optional ,本该是同一种目的凭空多出来不同的不兼容的表达方式乃至于扭曲目的本身(不顾历史,强行为现状洗地而寻找不同的用例场合),混起来效果就很感人了。

多几种其实不是直接问题。上古的 cons pair 限制个别元素就能造出 list monad ,用比较现代一点的说法,决定限制的 unit predicate 是 null?;中古一点的 string 同样也是个 monad ,unit pred 是 string-null? 。其实吧,传统数学上 list 和 string 可以就是一回事。那为什么不嫌弃 string 和 list 共存冗余呢?因为 string 好歹有复杂度 hint 表明适合不同场景(激进一点的还有 encoding 甚至 SSO 之类的假设,但把本属于 text 的东西混同 string 有过度设计的问题,这又是另一回事了)。这个意义上 string 是具有更多实现假设的 list 又确实不都能替代 string ,这种不同层次上的冗余适应新的需求,其实不难接受。问题是引入的目的和过程。新增的抽象如果没有提供更详细的假设提升到接口的含义,而仅仅是为了给不完善的旧有抽象擦屁股,但被擦屁股的东西又因为兼容性之类的原因没法被彻底替代而只能共存,这样缝合的下场自然不会让用户舒服了。为什么说 null 是多余的呢?因为 nullable type 历史上本来就是实现偷懒( null pointer )的结果上反向臆造的抽象。要从需求侧讲,没什么和 Maybe 区分的必要,反倒是传统实现习惯(比如死板的错误处理)导致使用者体验很尴尬。相比之下,C++一样也有 optional<T&>不能随便和 T*等价的历史包袱,这里思想包袱就体现得更明显,因为 nullptr 并没有 Java 一样被迫弄得到处都是的存在感,兼容性问题本该不是借口。

null 我觉得还好,不好的点是没有把 null 做到编译期,实际上可 null 就是一个简单的联合类型如果把 null 像 kotlin/ts/c#/Swift/dart 直接做到编译期,我觉得就没啥问题了Optional 太长太难用了,还是编译期 null 校验+可选链更好用

补充一个小点: 在 JDK8 时,使用 Optional 总感觉少了个功能, 在一堆链式调用后,只有 ifPresent 方法, 不为空的情况下才能执行, 还是需要 if 语句来判断是否为空。后面发现 JDK9 添加了一个 ifPresentOrElse 方法来解决这个问题。

补充代码 People p = null; // TODO: Optional people = Optional.ofNullable(p); Map<String, String> result = new HashMap<>(); people.map(People::getUsername) .ifPresentOrElse(e -> { result.put("status", "1"); result.put("name", e); }, () -> { result.put("status", "?"); }); System.out.println(result);