Optional用好了,缓解了多年NullPointerException恐惧。

💡 原文中文,约7100字,阅读约需17分钟。
📝

内容提要

Optional是JDK1.8引入的一个新特性,用于缓解Java中的NullPointerException问题。它作为一个容器,可以保存类型T的值,也可以保存null。Optional提供了一些方法,如empty、of、ofNullable、isPresent、orElse、orElseGet、get、map和flatMap等。在实际开发中,可以灵活运用Optional来获取复杂数据结构中的数据,并有效地防止NullPointerException的出现。

🔎

延伸解读

Optional 的适用场景与局限

Optional 主要用于方法返回值,以明确表示可能缺失的值,从而减少调用方的空指针检查。它并非用于替代所有 null 检查,也不适合作为字段类型或方法参数,因为这会增加不必要的包装。在文章示例中,Optional 与 Stream 结合处理集合数据,能优雅地提取嵌套属性,但需注意避免过度使用导致代码复杂化。

orElse 与 orElseGet 的求值差异

orElse 和 orElseGet 在 Optional 为空时都返回默认值,但求值时机不同:orElse 的参数总是会被提前计算,即使 Optional 有值;而 orElseGet 接受 Supplier,仅在 Optional 为空时才调用。因此,当默认值的创建成本较高或具有副作用时,应优先使用 orElseGet,以避免不必要的性能开销。

map 与 flatMap 的选择

map 和 flatMap 都用于转换 Optional 中的值,但 map 的映射函数返回普通值,而 flatMap 要求返回 Optional。当转换函数本身可能返回 null 或已返回 Optional 时,应使用 flatMap 以避免嵌套 Optional。例如,若方法返回 Optional<Position>,则需用 flatMap 展平,否则会得到 Optional<Optional<Position>>。

避免 Optional 的误用

使用 Optional 时,应避免直接调用 get() 而不检查存在性,否则可能抛出 NoSuchElementException。也不建议用 isPresent() 配合 if 语句,这并未简化空值检查。正确的做法是结合 orElse、orElseGet、ifPresent 或 map 等方法进行链式处理,从而真正发挥 Optional 减少空指针异常的优势。

❓

Q&A

Optional在Java中有什么作用?

Optional用于缓解Java中的NullPointerException问题,作为一个容器可以保存类型T的值或null。

如何创建一个空的Optional对象?

可以使用Optional.empty()方法来创建一个空的Optional对象。

Optional的of和ofNullable方法有什么区别?

of方法创建非空的Optional,若值为null则抛出异常;ofNullable方法则允许值为null,若值为null则返回空的Optional。

Optional的isPresent方法有什么用?

isPresent方法用于判断Optional中是否包含值,返回true或false。

如何使用Optional提供默认值?

可以使用orElse或orElseGet方法,在Optional没有值时提供默认值,orElse会提前创建值,而orElseGet在需要时才创建。

Optional如何与Stream结合使用?

Optional常与Stream结合使用,以便更方便地处理复杂数据结构中的数据,避免空指针异常。

➡️

继续阅读