相信很多小伙伴在工作中会遇到各种各样的空指针(NullPointerException) 异常,接下来举一些例子如何使用Optional 语法来优化代码
package com.zh.service;import lombok.Data;import java.util.Optional;
/**
* @Description: 测试Optional 断言
* @ClassName TestOptional
* @date:2022年-01月-15日 14:51
* @Author: zhanghang
*/
public class TestOptional {
@Data
static class A{
private String name;
private Integer age;
private B b;
}
@Data
static class B{
private String nameB;
private Integer ageB;
}
/**
* description: 需求:获取A 对象中的B 属性中的nameB 属性 ,如果为空,则返回空字符串
* date: 2022年-01月-15日 14:52
* author: zhanghang
*
* @param a
* @return String
*/
public String getAInBNameB(A a){
if (a != null){
if (a.getB() != null){
return a.getB().getNameB();
}
}
return "";
}
public static void main(String[] args) {
}}
特别是如果是多层包含的关系,那这样的判断会更加的繁琐以及代码的可观度也不好
这个时候Java8 就提供的一个工具类Optional
我们先看它的源码
package java.util;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Predicate;import java.util.function.Supplier;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
// 存放入参值
private final T value;
// 私有无参构造
private Optional() {
this.value = null;
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
// 私有有参构造
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public boolean isPresent() {
return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate);
if (!isPresent())
return this; else
return predicate.test(value) ? this : empty();
}
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
方法详解
-
根据它的源码发现了两个构造方法都是有私有的构造,所以不能够直接去new
我们看他的其他方法
-
of 和 ofNullable of 方法内部调用了有参 构造方法,有参构造方法调用了requireNonNull(T obj)方法,而requireNonNull方法内部做了非null 判断,如果入参为null ,则抛出异常,所以得出结论,如果使用public static
-
-
ofNullable方法是可以接受参数为null,不会抛出异常,
-
isPresent() 和 ifPresent(Consumer<? super T> consumer)
isPresent() 是判断value,也就是调用ofNullable 方法时的入参是否为null,为null则返回true,否则发挥false.
ifPresent(Consumer<? super T> consumer) 这个方法的入参是一个lambda表达式,如果value不为null,就执行表达式,
-
map 和 flatMap 方法
map 方法 和flatMap 方法的入参都是lambda 表达式,不同的是map方法的参数是个当包含的对象不为null时才执行的lambda表达式,返回该表达式执行结果的封装optional对象,同理支持链式调用,逐层深入和递归递进很像; flatMap区别在于lambda表达式的返回结果必须主动包裹Optinoal,否则报错map 方法 和flatMap 方法的入参都是lambda 表达式,不同的是map方法的参数是个当包含的对象不为null时才执行的lambda表达式,返回该表达式执行结果的封装optional对象,同理支持链式调用,逐层深入和递归递进很像; flatMap区别在于lambda表达式的返回结果必须主动包裹Optinoal,否则报错
-
orElse 和 orElseGet
orElse 当optional内对象为null就返回这个参数,比较像很多默认值设置; orElseGet 基本同orElse,区别是传入参数支持lambda表达式,返回的就是表达式执行结果; orElseThrow 也是传入lambda表达式,但是表达式是抛出异常
-
filter
filter 方法是一个过滤方法,根stream流式计算的filter 一样
public static void main(String[] args) {
A a = new A();
// 需求一: 获取A 对象中的B 属性中的nameB,如果为null则返回空字符串
String need1 = Optional.ofNullable(a).map(aa -> aa.getB()).map(b -> b.getNameB()).orElse("");
System.out.println("need1 -> "+ need1);
}
所以在项目中遇到空指针或者其他问题,可以优先使用java8给我们提供的Optional工具类。
关注成都知了堂,获得更多学习资料:https://zhiliaotang.cn