Hongwei's Diary
Fork me on GitHub

Java 8 Optional

2018-08-15

Optional类

  • Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
  • Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
  • Optional 类的引入很好的解决空指针异常。

一、构造实例

  • Optional opt = Optional.empty(); ##创建一个空 Optional
  • Optional opt = Optional.of(user); ##user不能为null
  • Optional opt = Optional.ofNullable(user); ##user可以为null

二、主要方法

public T get() 
public boolean isPresent()
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
public T orElse(T other)
public T orElseGet(Supplier<? extends T> other)
public void ifPresent(Consumer<? super T> consumer)
public Optional<T> filter(Predicate<? super T> predicate)
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X

三、开始使用

没有 Optional 之前,都是这么来写~

public void delJob(String jobId) {
CheckJob object = checkJobRepository.findOne(Long.valueOf(jobId));
if (object != null){
checkJobRepository.delete(object);
}
}

当有了 Optional ,于是代码就开始这么写了……

public void delJob(String jobId) {
Optional<CheckJob> object = checkJobRepository.findById(Long.valueOf(jobId));
if (object.isPresent()) {
checkJobRepository.delete(object.get());
}
}

这…和没用有什么区别嘛。。

四、正确姿势

public void delJobDemo(String jobId) {
Optional<CheckJob> object = checkJobRepository.findById(Long.valueOf(jobId));
object.ifPresent(checkJob -> checkJobRepository.delete(checkJob));
}
@GetMapping("/account")
@Timed
public BaseRestResponse getAccount() {
return BaseRestResponse.ok(userService.getUserWithAuthorities()
.map(UserDTO::new)
.orElseThrow(() -> new InternalServerErrorException("User could not be found")));
}

五、使用注意事项

直白的讲, 当我们还在以如下几种方式使用 Optional 时, 就得开始检视自己了

  • 调用 isPresent() 方法时
  • 调用 get() 方法时
  • Optional 类型作为类/实例属性时
  • Optional 类型作为方法参数时

注意:

  1. isPresent() 与 obj != null 无任何分别, 而没有 isPresent() 作铺垫的 get() 调用在 IntelliJ IDEA 中会收到告警
  2. Optional 类型不可被序列化, 用作字段类型会出问题
    使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法

六、常见Optional使用demo

1、存在即返回, 无则提供默认值

return user.orElse(null);  // 而不是 return user.isPresent() ? user.get() : null;return user.orElse(UNKNOWN_USER);

2、存在即返回, 无则由函数来产生

return user.orElseGet(() -> fetchAUserFromDatabase()); 
//而不要 return user.isPresent() ? user: fetchAUserFromDatabase();

3、存在才对它做点什么

user.ifPresent(System.out::println);
//而不要下边那样
if (user.isPresent()) {
System.out.println(user.get());
}
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章