java8出现的Option类

写过 Java 程序的同学,一般都遇到过 NullPointerException —— 为了不抛出这个异常,我们便会写如下的代码:

User user = getUserById(id);

if (user != null) {

String username = user.getUsername();

System.out.println("Username is: " + username); // 使用 username

}

但是很多时候,我们可能会忘记写 if (user != null) —— 如果在开发阶段就发现那还好,但是如果在开发阶段没有测试到问题,等到上线却出了 NullPointerException … 画面太美,我不敢继续想下去。

为了解决这种尴尬的处境,JDK 终于在 Java8 的时候加入了 Optional 类。Optional 的 javadoc 介绍:

A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

这是一个可以包含或者不包含非 null 值的容器。如果值存在则 isPresent()方法会返回 true,调用 get() 方法会返回该对象。

java.util.Optional

JDK 提供三个静态方法来构造一个 Optional:

1.Optional.of(T value),该方法通过一个非 null 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException。

2.Optional.ofNullable(T value),该方法和 of 方法的区别在于,传入的参数可以为 null —— 但是前面 javadoc 不是说 Optional 只能包含非 null 值吗?我们可以看看 ofNullable 方法的源码:

Optional.ofNullable 方法

原来该方法会判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。

3.Optional.empty(),该方法用来构造一个空的 Optional,即该 Optional 中不包含值 —— 其实底层实现还是 如果 Optional 中的 value 为 null 则该 Optional 为不包含值的状态,然后在 API 层面将 Optional 表现的不能包含 null 值,使得 Optional 只存在 包含值 和 不包含值 两种状态。

Optional.empty() 的实现

前面 javadoc 也有提到,Optional 的 isPresent() 方法用来判断是否包含值,get() 用来获取 Optional 包含的值 —— 值得注意的是,如果值不存在,即在一个Optional.empty 上调用 get() 方法的话,将会抛出 NoSuchElementException 异常。

我们假设 getUserById 已经是个客观存在的不能改变的方法,那么利用 isPresent 和 get 两个方法,我们现在能写出下面的代码:

Optional user = Optional.ofNullable(getUserById(id));

if (user.isPresent()) {

String username = user.get().getUsername();

System.out.println("Username is: " + username); // 使用 username

}

好像看着代码是优美了点 —— 但是事实上这与之前判断 null 值的代码没有本质的区别,反而用 Optional 去封装 value,增加了代码量。所以我们来看看 Optional 还提供了哪些方法,让我们更好的(以正确的姿势)使用 Optional。

1.ifPresent

Optional.ifPresent

如果 Optional 中有值,则对该值调用 consumer.accept,否则什么也不做。

所以对于上面的例子,我们可以修改为:

Optional user = Optional.ofNullable(getUserById(id));

user.ifPresent(u -> System.out.println("Username is: " + u.getUsername()));

T aaaa.orElse(T)方法

源代码

/**
* Return the value if present, otherwise return {@code other}.
*
* @param other the value to be returned if there is no value present, may
* be null
* @return the value, if present, otherwise {@code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}

@Override
    public ProductCategory findOne(Integer categoryId) {
        Optional<ProductCategory> optionalProductCategory = productCategoryRepository.findById(categoryId);
        return optionalProductCategory.orElse(null);
    }

你可能感兴趣的:(JAVA)