java 8 新特性 如何正确使用Optional

Optional<T> 对象是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象。对于第一种情况,我们称这种值为存在的。Optional<T> 类型被当作一种更安全的方式,用来代替类型T的引用,这种引用要么引用某个对象,要么为null。

Optional 作为Java 8 新特性之一,用来解决空指针异常。但是,它只有在正确使用的情况下才会更安全。

创建实例

Optional 有两个构造函数,但是都被private修饰。因此只能通过Optional 提供的三个静态方法来实例化对象:

  1. of(T value) : 返回value非null的Optional对象,否则会报错
  2. empty() : 返回value为null的Optional对象
  3. ofNullable(T value) : 返回value的Optional对象,如果value为null则返回一个空Optional

示例:

1
2
3
4
5
6
7
8
Integer val1 = null;
Integer val2 = 10;

Optional<Integer> a = Optional.of(val2);

Optional<Integer> b = Optional.empty();

Optional<Integer> c = Optional.ofNullable(val1);

实用方法

  • orElse(T other) 如果存在该值,返回值, 否则返回 other
1
2
Integer result = a.orElse(5);  // result = 10
Integer result = b.orElse(5); // result = 5
  • orElseGet(Supplier<? extends T> other) 如果存在该值,返回值,否则触发 other,并返回 other 调用的结果
1
Integer result = c.orElseGet(() -> Integer.sum(2,5));  // result = 7
  • orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
1
Integer result = b.orElseThrow(IllegalStateException::new);
  • ifPresent() 如果值存在则使用该值调用 consumer , 否则不做任何事情
1
2
3
List<Integer> lists = new ArrayList<>();

a.ifPresent(v -> lists.add(v));
  • map(Function<? super T,? extends U> mapper) 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional
1
Optional<Boolean> result = a.map(v -> v.compareTo(5));
  • filter(Predicate<? super <T> predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional
1
Optional<Integer> result = a.filter(v -> a > 10);
  • flatMap(Function<? super T,Optional<U>> mapper) 如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
1
Optional<Double> result = Optional.of(-4.0).flatMap(MyMath::inverse).flatMap(MyMath::squareRoot);
  • get() 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
1
System.out.print(a.get()); // 10
  • isPresent() 如果值存在则方法会返回true,否则返回 false
1
2
System.out.print(a.isPresent()); // true
System.out.print(b.isPresent()); // false

错误使用方式

如果没有正确使用Optional 值,那么相比于以往的是否为null校验,并没有任何的好处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 案例一
Optional<T> value = ...;
value.get().someMethod();

// 相比于

T value = ...;
value.someMethod();

// 案例二
if (value.isPresent()) value.get().someMethod();

// 相比于

if (value != null) value.someMethod();
z.h.l wechat
欢迎您扫一扫,订阅我的微信公众号