Optional
Java8中引入java.util.Optional,这是一个封装Optional值的类。
举例来说,如果一个人可能有也可能没有车,那么Person类内部的car变量就不应该声明为Car,遭遇某人没有车时不应该把null引用赋值给它,而是应该将其声明为Optional类型。
在代码中始终如一地使用Optional,能非常清晰地界定出变量值的缺失是结构上的问题,还是算法上的缺陷,抑或是数据中的问题。
引入Optional类的意图并非要消除每一个null引用。与此相反,它的目标是帮助更好地设计出普适的API,以便看到方法签名,就能了解它是否接受一个Optional的值。这种强制会积极的将变量从Optional中解包出来,直面缺失的变量值。
举个例子:
User user = getUserById(id);
if (user != null) {
String username = user.getUsername();
System.out.println("Username is: " + username); // 使用 username
}
但是很多时候,我们可能会忘记写 if (user != null)—— 如果在开发阶段就发现那还好,但是如果在开发阶段没有测试到问题,等到上线却出了 NullPointerException ...
创建Optional对象
Optional.empty,创建一个空的Optional对象.
Optional.of(T value),该方法通过一个非null的value来构造一个Optional,返回的Optional包含了value这个值。对于该方法,传入的参数一定不能为null,否则便会抛出NullPointerExceptionOptional.ofNullable(T value),该方法和of方法的区别在于,传入的参数可以为null。该方法会判断传入的参数是否为null,如果为null的话,返回的就是Optional.empty()Optional.empty(),该方法用来构造一个空的Optional,即该Optional中不包含值 —— 其实底层实现还是 如果Optional中的value为null则该Optional为不包含值的状态,然后在 API 层面将Optional表现的不能包含null值,使得Optional只存在 包含值 和 不包含值 两种状态。
方法
Optional 的 isPresent() 方法用来判断是否包含值,get() 用来获取 Optional 包含的值 —— 值得注意的是,如果值不存在,即在一个Optional.empty上调用 get()方法的话,将会抛出 NoSuchElementException 异常。 我们假设 getUserById 已经是个客观存在的不能改变的方法,那么利用 isPresent 和 get 两个方法,我们现在能写出下面的代码:
Optional<User> 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。
ifPresent()orElse()filter()- ...