Java8之新特性--Optional类型详解
Java8中新增了许多新的特性,分别是Lambda,方法引用(一般配合Lambda使用),Date/Time API,Stream,Optional,Base64加密,Interface支持默认方法和静态方法,另外还新增了一些新引擎工具,新增了对JavaScript的解释器-Nashorn。
本章主要讲下Optional类型的使用:
1、概念:Optional<>类型提供了一个容器,主要是检查容器中的元素是否为NULL。提到容器,很多Java小伙伴想到了List、Map、Set等,Optional最大的区别就是它只能插入一个元素,并会判断插入的元素是否为NULL
2、Optional 版本:@since 1.8,可以查看源码对照下面的API详细的介绍来学习
2、常用API介绍
(1)static Optional empty()
定义:构建一个空的Optional容器,相当与List list = new ArrayList(),里面没有任何元素,但在堆中已分配了空间
源码:
private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
分析:empty()方法中调用静态常量EMPTY 使用实例化new的方式构建一个空的容器
(2)static Optional of(T value)
定义:向Optional容器中插入一个元素,并检查这个元素是否为NULL,如果为NULL就抛异常;如果不为NULL,就会把这个元素插进去,并返回Optional对象
源码:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
分析:of()方法中实例化了一个Optional容器,并将传入的值插入到容器中,在constructor方法中,调用Objects类的requireNonNull() 方法;如果值为NULL,就抛出空指针异常
(3)static Optional ofNullable(T value) (empty()与of()方法的结合)
定义:向Optional容器中插入一个元素,并检查这个元素是否为NULL,如果为NULL,会构建一个空的容器,并返回Optional对象;如果不为NULL,就会把这个元素插进去,并返回Optional对象
ofNullable()与of()的最大区别就在于前者遇到NULL时,不做处理,会返回一个空的Optional容器对象,后者遇到NULL时,直接抛空指针(NullPointerException)异常
源码:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
分析:ofNullable()方法使用三目运算,如果传入的对象为NULL,调用empty()方法,构建一个空的Optional容器对象;如果不为NULL,调用of()方法,将该元素插入到容器中,并返回Optional容器对象
调用的empty()方法与of(value)方法是对应上方的(1)(2)讲的两个方法
(4)T get()
定义:获取Optional容器中的元素,与List的get(int index)方法类似,由于Optional容器中只能存入一个值,所以get时,无需指定索引
源码:(实例方法,需要使用Optional对象调用)
private final T value;
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
分析:get()方法会判断当前容器中是否存在元素,如果不存在,会抛出NoSuchElementException异常;如果存在会返回该元素
(5)boolean isPresent()
定义:判断当前容器中的元素是否为NULL,如果为NULL,返回true,否则false(一般该方法与get()结合使用)
源码:
public boolean isPresent() {
return value != null;
}
(6)T orElseGet(Supplier<? extends T> other)
定义:判断当前容器中的元素是否为NULL,如果不为NULL,返回该元素;如果为NULL,执行lambda参数(方法体)
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
例如:
static String print() {
System.out.println("Hello world!");
return "success";
}
public static void main(final String... args) {
System.out.println(Optional.of("A").orElseGet(() -> print()));
}
注:() -> print() 是lambda表达式的写法(lambda允许将方法体当成参数传递给另一个方法)后面章节会讲到!
(7)T orElseThrow(Supplier<? extends X> exceptionSupplier)
定义:检查容器中的元素是否为NULL,如果不为NULL,正常返回该元素;如果为NULL,抛出传入的异常(自定义异常)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
例如:(频繁会用到)
public Document findById(String id) throws UCException {
return documentRepository.findById(id).orElseThrow(
() -> new UCException(HttpStatus.NOT_FOUND, ErrorCode.DOCUMENT_NOT_FOUND, id));
}
分析:Supplier是@FunctionInterface函数式接口,这里先不做了解,后面章节会讲到!事例中的fingById()方法是从数据库中通过ID查询实体,如果没有查询到,结果为NULL,这里会直接抛出预先定义的异常,只需在Controller统一捕获就可以了,这样的话就不用在Service中判断==Null,不用特意通知前端了,非常简单实用!
以上就是开发中经常会用到的一些Optional API!
本章节就先讲到这里,对Optional类型的使用还有不明白的,或者在整合到项目中出错的,欢迎加博主QQ:1402218191 !
下一篇: 《吊打面试官》系列-Redis基础