Optional 的正确用法
Optional 的不正确实践
首先,不要直接拿来做if-else
的判定条件,这肯定是错的:
1 |
|
而且get()
要配合isPresent()
才安全。
其次,尽量不要用 Optional 拿来做成员变量,特别是 pojo 的成员变量,这很容易让读 pojo 的框架出问题。
再次,不要拿来做方法参数,因为很可能写成 if (user.isPresent()) {}
式的代码。
最后,Optional 的关注点在它的 value 的后续处理身上,如果这个 value 只是一个 flag,还是要乖乖地用if-else
;如果这个 value 被用在多路返回里,也不能使用 Optional。
正确的用法
选对构造器
Optional.of(T value)
如果需要断言值不为空,使用这个构造器。
该方法通过一个非 null 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException。
Optional.ofNullable(T value)
如果这个值可以为空,使用这个构造器。
该方法和 of 方法的区别在于,传入的参数可以为 null , 但是前面 javadoc 不是说 Optional 只能包含非 null 值吗?原来该方法会判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。
Optional.empty()
最好搭配其他构造器使用这个方法。
该方法用来构造一个空的 Optional,即该 Optional 中不包含值,其实底层实现还是 如果 Optional 中的 value 为 null 则该 Optional 为不包含值的状态,然后在 API 层面将 Optional 表现的不能包含 null 值,使得 Optional 只存在 包含值 和 不包含值 两种状态。
选对返回值
要用orElse
、orElseGet
、map + collect
来打扁结构,注意这几个方法是休止方法。很适合拿来配合 supplier 一起使用。
1 |
|
选对消费者
ifPresent
可以用来接受闭包,实现 cps 风格,很适合搭配 consumer 一起使用。
1 |
|
Java 9 对Optional的增强
or方法
or 方法的作用是,如果一个 Optional 包含值,则返回自己;否则返回由参数 supplier 获得的 Optional
ifPresentOrElse
ifPresentOrElse 方法的用途是,如果一个 Optional 包含值,则对其包含的值调用函数 action,即 action.accept(value),这与 ifPresent 一致;与 ifPresent 方法的区别在于,ifPresentOrElse 还有第二个参数 emptyAction —— 如果 Optional 不包含值,那么 ifPresentOrElse 便会调用 emptyAction,即 emptyAction.run()
stream
stream 方法的作用就是将 Optional 转为一个 Stream,如果该 Optional 中包含值,那么就返回包含这个值的 Stream;否则返回一个空的 Stream(Stream.empty())。
举个例子,在 Java8,我们会写下面的代码:
1 |
|
而有了 Optional.stream(),我们就可以将其简化为
1 |
|
参考文献: