Optional提供了多种方法可以从Optional类型中读取值的方法,我们来看一下方法和对应的源码。
1、get()是这些方法中最简单的方法,直接获取Optional中的值,但又最不安全的方法。如果变量存在,它直接返回变量值,否则就抛出一个NoSuchElementException异常。这个方法不建议使用,除非你确定其中一定包含变量值。
看源码:
/**
* If a value is present in this {@code Optional}, returns the value,
* otherwise throws {@code NoSuchElementException}.
*
* @return the non-null value held by this {@code Optional}
* @throws NoSuchElementException if there is no value present
*
* @see Optional#isPresent()
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
2、orElse(T other),当Optional对象不包含值时提供一个默认值,这个方法其实相当于一个三目运算符,例如:address !=null ? address:new Addrsss()
看源码:
/**
* 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;
}
3、orElseGet(Supplier other),是orElse方法的延迟调用版,或者说是性能提升版,如果Optional中的值为空,才调用这个方法,那么这个逻辑的作用是什么?如果是为空时创建的替补对象非常复杂时,可以用这个方法,程序就不需要浪费资源去创建可能不用的对象了(如果Optional中的值不为空,就不会创建替补对象)。
看源码:
/**
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
*
* @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方法的参数本身就是一个lambda表达式,只有执行到自己的分支,才执行这个方法,也就是other.get()才开始执行,这就实现了延时创建的效果。
4、orElseThrow(Supplier exceptionSupplier)和get方法非常类似,Optional对象为空时都会抛出一个异常,但是使用orElseThrow抛出自定义的异常类型。
看源码:
/**
* 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 <X> 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();
}
}
5、ifPresent(Consumer)作用是判断Optonal中的值是否为空,存在值返回true,否则false。
看源码:
/**
* Return {@code true} if there is a value present, otherwise {@code false}.
*
* @return {@code true} if there is a value present, otherwise {@code false}
*/
public boolean isPresent() {
return value != null;
}