空指针异常(NullPointException,简称 NPE)可以说是所有 Java 程序员都遇到过的一个异常,虽然 Java 从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而 Java 设计者也只能是让指针在 Java 语言中变得更加简单易用,而不能完全剔除,所以才有了常见对的关键字 null。

Java 8 Optional:优雅地躲避 NPE

因此 Java 8 使用 Optional 类来避免 NPE 问题,提升了代码的美观度。但并不是对 null 关键字的一种替代,而是对于 null 判定提供了一种更加优雅的实现,从而避免 NPE 问题。

of: 为非 null 的值创建一个 Optional。 创建对象时传入的参数不能为 null。 如果传入参数为 null, 则抛出 NullPointerException
ofNullable: 为指定的值创建一个 Optional, 如果指定的值为 null, 则返回一个空的 Optional

  1. //下面创建了一个不包含任何值的Optional实例
  2. //例如,值为'null'
  3. Optional empty = Optional.ofNullable(null);

isPresent: 如果值存在返回 true, 否则返回 false

  1. //ifPresent方法接受lambda表达式作为参数。
  2. //lambda表达式对Optional的值调用consumer进行处理。
  3. name.ifPresent((value) -> {
  4. System.out.println("The length of the value is: " + value.length());
  5. });

ofNullable: 为指定的值创建一个 Optional, 如果指定的值为 null, 则返回一个空的 Optional
orElse: 如果Optional实例有值则将其返回,否则返回orElse方法传入的参数

  1. user = Optional.ofNullable(user).orElse(new User());
  2. // 上一行代码 等价于 下一行代码
  3. user = (user == null) ? new User() : user;

orElse 和 orElseGet 的区别
当 Optonal 的值是空值时, 无论 orElse 还是 orElseGet 都会执行; 而当返回的 Optional 有值时, orElse 会执行, 而 orElseGet 不会执行。 因此, orElseGet 方法在性能上要优于 orElse 方法
orElseGet可以接受一个lambda表达式生成默认值

  1. //输出:Default Value
  2. System.out.println(empty.orElseGet(() -> "Default Value"));
  3. //输出:Sanaulla
  4. System.out.println(name.orElseGet(() -> "Default Value"));



map: 如果有值, 则对其执行调用 mapping 函数得到返回值。 如果返回值不为 null, 则创建包含 mapping 返回值的 Optional 作为 map 方法返回值, 否则返回空 Optional
filter: 如果有值并且满足断言条件返回包含该值的 Optional, 否则返回空 Optional

  1. RltData data = new RltData("20191008125000", new BigDecimal(10000), (byte)1);
  2. Result result = new Result(10, data);
  3. Response response = new Response(1000, "success", result);
  4. String rlt = checkRlt(response);
  5. System.out.println(rlt);
  6. private static String checkRlt(Response response) {
  7. return Optional.ofNullable(response)
  8. .map(Response::getResult)
  9. .map(Result::getData)
  10. .map(RltData::getOrderNo).orElse("none");
  11. }

注意事项

Optional 是一个 final 类,未实现任何接口,Optional 不能序列化,不能作为类的字段
可以通过自己实现 getter 方法,使 Lomok 不自动生成

Java 14 Helpful NullPointerExceptions

  1. <br /> 在JDK14中,当运行期,试图对一个bull对象进行应用时,JVM依然会抛出一个NullPointerException (NPE),除此之外,还会通过通过分析程序的字节码指令,JVM将精确地确定哪个变量是null,并且在堆栈信息中明确的提示出来。

在JDK 14中,如果上文中的a.i = 99发生NPE,将会打印如下堆栈:

Exception in thread "main" java.lang.NullPointerException: 
        Cannot assign field "i" because "a" is null
    at Prog.main(Prog.java:5)

这算是JDK的一个小小的改进,但是这个改进对于开发者来说确实是非常友好的。

————————————————
参考文章
链接:https://blog.csdn.net/u010979642/article/details/92836865