Java8新增了Optional包装类,旨在尽可能的避免NPE的问题。
首先,Optional是一个容器,用于放置可能为空的值,它可以合理而优雅的处理null。
Optional表示空的静态方法为Optional.empty(),其实是在null的外面做了一层包装,同时,包装类提供了很多方法。
基于Java8同时加入了函数式风格及lambda表达式,Optional类提供的方法也是基于此,Optional类希望对于可能为空的值,一直在Optional包装类中进行函数计算或提取。Optional类的方法,在执行前,很多都会对数据进行空校验,从而达到尽可能避免NPE的出现。
1. Optional.of()/Optional.ofNullable() : 创建Optional对象
.of() 创建一个Optional对象,如果 value 是 null,则抛出 NPE。ofNullable()则无此限制。
String empty = null; Optional<String> emptyOpt = Optional.ofNullable(empty); // 抛异常 Optional<String> empty2Opt = Optional.of(empty);
不推荐使用 .of()
2. isPresent() : 判断值是否存在,返回boolean值
Optional<String> testOpt = Optional.ofNullable("test"); System.out.println(testOpt.isPresent() == true);
判断Optional中是否有值,返回 boolean,某些情况下很有用,但尽量不要用在 if 判断体中?
3. ifPresent(Consumer<? super T> consumer) : 如果option对象保存的值不是null,则调用consumer对象,否则不调用
Optional<String> testOpt = Optional.ofNullable("test"); testOpt.ifPresent(s -> System.out.println(s));
推荐使用,没有性能上的优势,但可以使代码更简洁。同时也是Java8希望使用的风格。
4. get()/orElse(value)/orElseGet(Supplier<? extends T> other)
get() 返回Optional中包装的值,在判空之前,千万不要直接使用。
orElse(value) :如果optional对象保存的值不是null,则返回原来的值,否则返回value
orElseGet(Supplier supplier) :功能与orElse一样,只不过orElseGet参数是一个对象
Optional<String> testOpt = Optional.ofNullable(null); testOpt.orElseGet(() -> {
推荐使用orElseGet()
5. orElseThrow() :值不存在则抛出异常,存在则什么不做,有点类似Guava的Precoditions
6. filter (Predicate<? super T> predicate) :如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。
Optional<String> filterOpt = Optional.ofNullable("test"); Optional<String> middleOpt = filterOpt.filter(s -> { System.out.println("进入Filter断言"); return "1".equalsIgnoreCase(s); }); // 当filter2Opt的value值为空时,则不执行断言 Optional<String> filter2Opt = Optional.ofNullable(null"); Optional<String> middle2Opt = filterOpt.filter(s -> { System.out.println("不进入Filter断言"); return "1".equalsIgnoreCase(s); });
当filter2Opt的value值为空时,则不执行断言,避免了NPE。
7. <U> Optional<U> map(Function<? super T, ? extends U> mapper) :如果参数 mapper 有值,则调用map方法执行mapper参数的Function方法得到返回值。如果mapper的返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。如果传入的mapper参数是null,抛出NPE
// mapOpt 的value值为空时,则不执行方法体 Optional<String> mapOpt = Optional.empty(); Optional<String> middleOpt = mapOpt.map(s -> { System.out.println("不进入Func"); return s + "1"; }); Optional<String> map2Opt = Optional.ofNullable("test"); Optional<String> middle2Opt = map2Opt.map(s -> { System.out.println("进入Func"); return s + "new"; });
map方法多用于,一系列调用方法,找到最后真正需要处理的对象,使用流式调用风格。代码更加整洁。