Optional类是为了避免空指针异常的发生
其中有三种创建Optional实例的方法,我们接下来进行分别介绍
第一种方法 ---- empty (静态方法)
源码:
// 静态方法,可以使用类名直接使用。
// 返回一个空的Optional实例。
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
示例代码:
Optional<String> optional = Optional.empty();
第二种方法 ---- of (静态方法)
源码:
//
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
示例代码:
// 直接定义值,返回一个值不为空的Optional示例
Optional<String> optionalS = Optional.of("hello");
第三种方法 ---- ofNullable(静态方法)
源码:
// 根据源码分析,这个方法跟of方法差不多,只是在判断了设置的值是否为null,
// 如果为null,返回空的Optional示例;否则,调用of方法,创建实例。
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
示例代码:
// 当不知道对象是否是null的时候,使用该方法
// 如果为null,返回空的Optional示例;否则,调用of方法,创建实例。
Optional<String> optionalS = Optional.ofNullable("hello");
前面讲了如何构造出Optional实例对象,接下来,就继续看看怎么取得Optional里面的值。
public boolean isPresent() {
return value != null;
}
// 如代码所示,使用get方法,就可以拿到值。
// 但是注意一点,首先第一行有一个判断,那么这个方法是干什么的呢。
// 上面的源码就是isPresent方法,直接就判断值是否为null。
if (optionalS.isPresent()) {
System.out.println(optional.get());
}
上面这种写法,跟下面的这个写法是没有任何区别的,所以是不推荐上面这种写法的。
if (null != optionalS) {
System.out.println(optionalS.get());
}
推荐的Optional使用方式
// 参数是consumer,消费者类型。如果值不为null,调用消费者返回值。
// 关于消费者类型接口下一篇会进行讲解
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
// 根据上面的源码分析,ifPresent方法会帮我们判断值是否为null;
// 如果不为null,返回值
optional.ifPresent(item -> System.out.println(item));
上面才是推荐的Optional使用的方式,但是这个时候也有一个小的技巧,当optional值为null时,他会返回null,但是大多是的时候,我们应该给前台返回一个空的list。这样前台在遍历list的时候,也就不会报错了。
// 判断值是否为null,返回相应的返回值
public T orElse(T other) {
return value != null ? value : other;
}
// 接收一个supplier接口类型的参数(供应商接口,不接收参数返回一个值,前面讲过),
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
// 下面这两种方法都是可以在optional为null时,返回相对应的自己设置的值
System.out.println(optionalS.orElse("world"));
System.out.println(optionalS.orElseGet(() -> "nihao"));
那么这两个方法有什么区别吗?
当然有区别了。
示例代码:
// 当optional实例有值的情况下,orElse方法还是会执行test方法;而orElseGet则不会执行,到此结束。
Optional<String> optional = Optional.of("aaaa");
System.out.println("orElse方法");
optional.orElse(test1());
System.out.println("orElseGet方法");
optional.orElseGet(() -> test1());
private static String test1() {
System.out.println("进入方法");
return null;
}
// 输出结果
orElse方法
进入方法
orElseGet方法
// 当optional实例的值为null的情况下,orElse方法还是会执行test方法;而orElseGet则不会执行,到此结束。
Optional<String> optional = Optional.empty();
System.out.println("orElse方法");
optional.orElse(test1());
System.out.println("orElseGet方法");
optional.orElseGet(() -> test1());
private static String test1() {
System.out.println("进入方法");
return null;
}
// 输出结果
orElse方法
进入方法
orElseGet方法
进入方法
上面使用的是单个实体,下面我们将使用列表来暂时怎么使用optional。
// 接收一个Function类型参数(函数式接口,接收一个值,返回一个值),返回Optional类型值。
// 这里的逻辑也很简单,判断参数
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));
}
}
Employee employee1 = new Employee();
employee1.setName("zhangsan");
Employee employee2 = new Employee();
employee2.setName("lisi");
Company company = new Company();
company.setName("company1");
List<Employee> employees = Arrays.asList(employee1,employee2);
company.setEmployeeList(employees);
Optional<Company> optionalCompany = Optional.ofNullable(company);
// 调用map方法,判断参数是否为null,如果为null,返回orElse方法里面的值
List<Employee> employees1 = optionalCompany.map(theCompany ->
theCompany.getEmployeeList()).orElse(Collections.emptyList());
System.out.println(employees1);
上面是Optional类的正确使用方法,很好的避免了空指针的异常。
自己还没怎么使用过,边学习边使用吧。一起加油。
一个问题:
如果上述的设置List这样写company.setEmployeeList(null);
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
map方法再调用Objects.requireNonNull()
时,为什么不抛出异常。如果你知道,请告诉我,谢谢。
来源:CSDN
作者:fh无敌
链接:https://blog.csdn.net/qq_38832908/article/details/103941908