我们都知道,Optional类是Java8为了解决null值判断问题,使用Optional类可以避免显式的判断null值(null的防御性检查),避免null导致的NPE(NullPointerException) 。
在介绍这三个方法之前,先讲讲 Optional 的 ofNullable() 方法,因为他们常常搭配一起使用。
我们来看看 ofNullable() 方法的源码:
/**
* A container object which may or may not contain a non-null value.
* If a value is present, {@code isPresent()} will return {@code true} and
* {@code get()} will return the value.
*/
public final class Optional<T> {
/**
* Common instance for {@code empty()}.
*/
private static final Optional<?> EMPTY = new Optional<>(); //执行Optional的无参构造
//无参构造
private Optional() {
this.value = null;
}
//有参构造
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
/**
* Returns an {@code Optional} describing the specified value, if non-null,
* otherwise returns an empty {@code Optional}.
* 如果value不是null, 返回它自己本身, 是空, 则执行empty(), 返回null
*
* @param the class of the value
* @param value the possibly-null value to describe
* @return an {@code Optional} with a present value if the specified value
* is non-null, otherwise an empty {@code Optional}
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/**
* Returns an empty {@code Optional} instance. No value is present for this
* Optional.
* 当value是空时, 返回Optional对象
*
* @apiNote Though it may be tempting to do so, avoid testing if an object
* is empty by comparing with {@code ==} against instances returned by
* {@code Option.empty()}. There is no guarantee that it is a singleton.
* Instead, use {@link #isPresent()}.
*
* @param Type of the non-existent value
* @return an empty {@code Optional}
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY; //由第一行代码可知, EMPTY是一个无参Optional对象
return t;
}
/**
* Returns an {@code Optional} with the specified present non-null value.
* 返回不等于null的value值本身
*
* @param the class of the value
* @param value the value to be present, which must be non-null
* @return an {@code Optional} with the value present
* @throws NullPointerException if value is null
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value); //执行Optional的有参构造
}
}
所以大家懂了吗? ofNullable() 就是做了null值判断, 所以我们直接调用此方法就可以了, 而不需要我们自己手动判断null值 。
而 orElse(),orElseGet() ,orElseThrow() 这三个方法都是用来处理null值的情况:
orElse() : 当值为null时, 返回的是该方法的参数 。但值不为null时, 返回值本身。
源码 :
/**
* Return the value if present, otherwise return {@code other}.
* 如果值存在(即不等于空), 返回值本身, 如果等于空, 就返回orElse()方法的参数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;
}
使用示例 :
如果ofNullable()不等于null, 则返回scRespDTO.getMsgBody().getSuccess()的值;
如果为null, 则返回false (即返回orElse()的参数)。
//如果ofNullable()不等于null, 则返回scRespDTO.getMsgBody().getSuccess()的值,
//如果为null, 则返回false (即返回orElse()的参数)
Optional.ofNullable(scRespDTO.getMsgBody().getSuccess()).orElse(false)
orElseGet() : 当值为null时, 返回的是实现了Supplier接口的对象的 get() 值 。但值不为null时, 返回值本身。
源码 :
/**
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
* 值如果存在(即不为空), 返回值本身, 如果不存在, 则返回实现了Supplier接口的对象.
* Supplier接口就只有一个get()方法. 无入参,出参要和Optional的对象同类型.
*
* @param other a {@code Supplier} whose result is returned if no value
* is present
* @return the value if present otherwise the result of {@code other.get()}
* @throws NullPointerException if value is not present and {@code other} is
* null
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
使用示例 :
// orElseGet 它可以传入一个supplier接口,里面可以花样实现逻辑
System.out.println(Optional.ofNullable("努力成为一名更优秀的程序媛").orElseGet(()->"你不够优秀")); // ofNullable()不为空,就输出"努力成为一名更优秀的程序媛",反之,则输出"你不够优秀"
System.out.println(Optional.ofNullable(null).orElseGet(()->"你没有努力")); // ofNullable()为null, 输出 "你没有努力"
【Tip: 肯定有很多小伙伴觉得 orElse() 和 orElseGet() 方法没有区别,当值为null时,两者都是返回这两方法的参数。但是区别就是,orElseGet() 并不是直接返回参数本身,而是返回参数的get()值,且该参数对象必须实现 supplier 接口(该接口为函数式接口)。这样使得orElseGet()更加灵活。】
orElseThrow() : 当值为null时, 返回的是实现了Supplier接口的对象的 get() 值 。但值不为null时, 返回值本身。
源码:
/**
* Return the contained value, if present, otherwise throw an exception
* to be created by the provided supplier.
*
* @apiNote A method reference to the exception constructor with an empty
* argument list can be used as the supplier. For example,
* {@code IllegalStateException::new}
*
* @param Type of the exception to be thrown
* @param exceptionSupplier The supplier which will return the exception to
* be thrown
* @return the present value
* @throws X if there is no value present
* @throws NullPointerException if no value is present and
* {@code exceptionSupplier} is null
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
使用示例 :
如果ofNullable()不等于null,则返回值本身,即user对象;
如果为null, 则发生指定的异常。(可以使用 :: 形式,这个冒号后面是自定义异常,还可以使用 Lambda 表达式直接引用Java类定义的异常。示例已演示了。)
//如果user对象为null,且new实现了异常,就以new的形式抛异常,否则抛ArithmeticException异常
Optional.ofNullable(user).orElseThrow(ArithmeticException::new));
//如果user对象不为null,返回该对象,否则抛NullPointerException。异常
//orElseThrow()如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
Optional.ofNullable(user).orElseThrow(() -> new NotFoundException("记录不存在"));
大家知道了吗?有没有帮助到你们呢?可以评论告诉我哦。
无论如何我们一起努力成长吖~ 成为一名更优秀的程序媛