Optional是这样用吗?

Optional是这样用吗?

如果你写的Java代码中还包含了对Null的判断,咦,是不是有点low了。本节主要包含了对JDKjava.util.Optional的理解。

使用Optional需要理解这几点精髓:

创建Optional对象

创建一个空对象

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Returns an empty {@code Optional} instance. No value is present for this
* 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 <T> Type of the non-existent value
* @return an empty {@code Optional}
*/
public static<T> Optional<T> empty()

这没什么好说的。

创建一个非空对象

1
2
3
4
5
6
7
8
9
/**
* Returns an {@code Optional} with the specified present non-null value.
*
* @param <T> 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)

需要注意的是参数value值不可以为空,否则会在运行期抛出NullPointerException

创建一个可以为空的对象

1
2
3
4
5
6
7
8
9
10
/**
* Returns an {@code Optional} describing the specified value, if non-null,
* otherwise returns an empty {@code Optional}.
*
* @param <T> 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)

这个就比较好用了,管你是空还是非空,都到碗里来。

对象转换(业务处理)

熟悉Java8相关Function的很容易理解

对Optional数据进行消费

1
public void ifPresent(Consumer<? super T> consumer)

参数为一个Consumer函数,你懂的

对Optional数据进行转换

1
2
3
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)

参数是一个Function函数,两者的区别在于转换结果对象不一样。

对Optional数据进行过滤

1
public Optional<T> filter(Predicate<? super T> predicate)

参数是一个Predicate函数

获取值

补偿输出

意思是如果当前Optional的值不为空则直接返回该值,如果该值为空,则返回另外一个值。Optional类提供了2个函数

1
2
3
public T orElse(T other);

public T orElseGet(Supplier<? extends T> other)

区别在于,orElse()接收一个参数作为返回,而orElseGet则是接收一个Supplier生产函数。

抛出异常

很多时候,我们对于Null业务的处理是抛出一个自定义异常。

1
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X;

参数是一个生产函数

Example

不使用Optional的写法

1
2
3
4
5
6
7
8
public void test() {
String name = getNameById(0);
if (name!=null) {
name = name.toUpperCase();
} else {
throw new NullPointerException();
}
}

使用Optional后,Null只在你心里

1
2
3
4
5
6
@Test
public void test() {
Optional<String> v = Optional.ofNullable(getNameById(0));
String name = v.map(String::toUpperCase)
.orElseThrow(NullPointerException::new);
}

总结

Optional简单,用法上也就上面提到的3类,对Function的理解是关键。

# java

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×