Java进阶篇(3)—Optional类(是否使用Optional来代替null)

JAVA && Spring && SpringBoot2.x — 学习目录

1. 为什么会出现Optional

Optional是JDK8出现,它位于java.util.Optional,它的出现旨在解决NPE问题,即空指针异常。Optional类,可以将其理解为一个容器,该容器包含null值或非null值。

空指针出现的根本原因在于代码逻辑的不严谨,即用户在尝试使用数据之前忘记通过!=null进行数据判断。

而Optional类似于异常检查,他会迫使用户去处理Optional中是否包含内容,从而避免因为忽略null值而导致潜在的隐患。

2. Optional的缺点

Optional的出现并不是为了替代null,甚至好多人认为Optional并不会使代码变得更好,他们认为

  1. 使用Optional的动机是使用户永远不要忘记进行非空检查,但是Optional并不能完全保证这一点,其他工具例如(Nullness_Checker)更加强大和精确,它们提供了编译时的保障。
  2. Optional并不会避免NPE问题,他只是将异常转化为NoSuchElementException
  3. Optional语法比使用可为空的引用更加难以理解。
  4. Optional效率比较低。

详见 —— Nothing is better than the Optional type(Option类并没有变得更好)

3. Optional的规范

阿里巴巴java开发手册。注:NPE即空指针异常

java规范中,对于级联调用这种易产生NPE问题场景,是推荐使用Optional类来防止NPE问题的。那么是不是所有的场景都可以使用Optional来代替null值?

Optional是一把双刃剑,可以使用链式来优雅的操作对象,但是Optional还是拥有着很多缺点,故如何正确的使用Optional将变得更加重要。

  1. Optional本身作为一个引用类型,本身也是会出现NPE问题的。倘若我们去担忧Optional对象是否为null,那么将会违背Optional设计的理念。故在任何时候都不要将Optional类赋值为null。

  2. Optional类若是单独调用get()方法,可能会导致NoSuchElementException,故在调用之前需要先调用isPresent()方法判断Optional容器中值是否存在。我们在使用Optional类时,最好不要使用这两个方法,而是应该使用Java进阶篇(2)—Optional类(预防空指针NPE)方法。

  3. 是否选择使用链式语法,是要根据场景,不能强行使用链式语法。例如使用三目表达式或者使用简单的if...else...语法能处理的,尽量使用null来判断。Optional操作不仅效率比较低,而且对于简单的条件判断,可读性也没有使用普通引用好。在阿里的Java开发规范中也指出了对于级联调用才采用Optional来避免NPE问题。

  4. 尽量避免将Optional用于类属性,方法参数及集合元素中,因为完全使用null值来替代Optional。没有必要使用Optional。时刻注意使用Optional的目的是提醒用户不要忽略NPE问题。

  5. 尽量避免使用Optional的== equals hashCode的方法,原因在于Optional虽然目前是reference type,但是在未来可能会被优化为value type。需要保证版本的兼容。

  6. Optional属性不可序列化,虽然目前为reference type类型,但若实现序列化,是无法转化为value type,考虑版本兼容问题,故Optional是禁止序列化的。

  7. Optional使用场景最好作为方法的返回值。

4. 替代方案

Spring+idea.png

其实optional是强制用户注意到返回值可能存在null的情况,但是Spring使用了@Nullable注解,然后idea编译的时候,就会提示用户,这个返回值可能为null。

推荐阅读

Java进阶篇(2)—Optional类(预防空指针NPE)

使用Optional的正确姿势及序列化问题

你可能感兴趣的:(Java进阶篇(3)—Optional类(是否使用Optional来代替null))