您当前的位置:首页 > 计算机 > 编程开发 > Java

Java8之新特性--Optional类型详解

时间:02-13来源:作者:点击数:

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!

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门