什么是 Optional 类?
Optional 是 JDK8 新增加的一个工具类,位于 java.util
包下。
Optional 类是一个可以为 null
的容器对象。如果值存在则 isPresent() 方法会返回 true
,调用 get() 方法会返回该对象。
Optional 是个容器:它可以保存类型 T
的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常(微笑)。
Optional 类的方法及使用
Optional 类中提供了一些常用的方法,同时结合 JDK8 的 Lambda 新特性使用,能够更加方便。
私有构造
1 | private Optional() { |
在 Optional 类中,构造函数被私有访问修饰符修饰,也就意味着我们无法使用 new
关键字来创建对象。
empty()
1 | Optional<User> empty = Optional.empty(); |
使用 Optional
类的静态方法 empty()
,可以创建一个容器内值为 null
的 Optional
对象。使用该方法,得到的 Optional
类是存在的,只不过该类中的值为 null
。
源码:
1 | private static final Optional<?> EMPTY = new Optional<>(); |
of(T value)
1 | User user1 = new User(); |
of(T value)
方法是 Optional
类创建容器的主要方法,使用该方法,可以创建一个泛型为 T
的 Optional
容器,并向容器内注入一个值对象。
需要注意的是,使用 of(T value)
方法,参数不可以为 null
,否则程序会报空指针异常。
源码:
1 | public static <T> Optional<T> of(T value) { |
1 | public static <T> T requireNonNull(T obj) { |
ofNullable(T value)
1 | User user1 = new User(); |
ofNullable(T value)
方法和 of(T value)
方法唯一的区别在于,参数可以为 null
,如果参数为 null
,会调用 empty()
方法返回一个空的 Optional
对象。
源码:
1 | public static <T> Optional<T> ofNullable(T value) { |
get()
1 | User user1 = new User(); |
get()
方法,用于返回 Optional
容器中的值对象。但是如果 Optional
容器为一个空容器,即内部的值为 null
,则会抛出 NoSuchElementException
异常。
源码:
1 | public T get() { |
isPresent()
1 | User user1 = new User(); |
isPresent()
方法,用于判断 Optional
容器内是否有值,有则返回 true
,否则返回 false
。
源码:
1 | public boolean isPresent() { |
ifPresent(Consumer<? super T> consumer)
1 | User user1 = new User(); |
ifPresent(Consumer<? super T> consumer)
方法,参数是一个消费型函数式接口,可以配合 Lambda 表达式使用。
该方法的作用为:如果 Optional
容器中有值,则执行 Consumer
接口中的方法,否则不做其他任何操作。
源码:
1 | public void ifPresent(Consumer<? super T> consumer) { |
filter(Predicate<? super T> predicate)
1 | User user1 = new User(); |
filter(Predicate<? super T> predicate)
方法用于过滤 Optional
容器中的值,如果 容器内的值符合 Predicate
函数所定义的接口,即返回 true
,则返回原来的 Optional
对象,否则返回空的 Optional
容器对象。
源码:
1 | public Optional<T> filter(Predicate<? super T> predicate) { |
map(Function<? super T, ? extends U> mapper)
1 | User user1 = new User(); |
map(Function<? super T, ? extends U> mapper)
方法,可以将 Optional
容器内的值替换为其他类型的值,具体的替换规则由 Function
函数定义。
例如上面的代码中,将 User
类型的 Optional
容器替换为了 String
类型的 Optional
容器。
源码:
1 | public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { |
flatMap(Function<? super T, Optional> mapper)
1 | User user1 = new User(); |
该方法与 map(Function<? super T, ? extends U> mapper)
方法类似,不过该方法要求在 Function
函数中返回 Optional
对象,并且返回的 Optional
对象不允许为 null
。
源码:
1 | public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { |
orElse(T other)
1 | User user1 = new User(); |
orElse(T other)
方法和 get()
方法类似,不过比 get()
方法多了一层保险机制,如果 Optional
容器中的值为 null
,则会返回 orElse(T other)
方法参数中的对象,该参数类型必须和 Optional
泛型类型一致。
源码:
1 | public T orElse(T other) { |
orElseGet(Supplier<? extends T> other)
1 | User user1 = new User(); |
该方法和功能类似,不过和 orElse(T other) 方法不同的是, Optional
容器中的值为 null
时返回的对象通过生产型函数接口来创建并返回。
源码:
1 | public T orElseGet(Supplier<? extends T> other) { |
orElseThrow(Supplier<? extends X> exceptionSupplier)
1 | User user1 = new User(); |
该方法的逻辑和 orElse(T other)
、orElseGet(Supplier<? extends T> other)
基本类似,不过当 Optional
容器的值为 null
时,会抛出生产型函数返回的异常对象。
源码:
1 | public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { |
其他方法
Optional
类除了上述的特有方法之外,还重写了 equals()
、hashCode()
、toString()
等通用方法,在本篇文章中不做过多的讲述。