空指针异常(NullPointException,简称 NPE)可以说是所有 Java 程序员都遇到过的一个异常,虽然 Java 从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而 Java 设计者也只能是让指针在 Java 语言中变得更加简单易用,而不能完全剔除,所以才有了常见对的关键字 null。
Java 8 Optional:优雅地躲避 NPE
因此 Java 8 使用 Optional 类来避免 NPE 问题,提升了代码的美观度。但并不是对 null 关键字的一种替代,而是对于 null 判定提供了一种更加优雅的实现,从而避免 NPE 问题。
of:
为非 null 的值创建一个 Optional。 创建对象时传入的参数不能为 null。 如果传入参数为 null, 则抛出 NullPointerExceptionofNullable:
为指定的值创建一个 Optional, 如果指定的值为 null, 则返回一个空的 Optional
//下面创建了一个不包含任何值的Optional实例
//例如,值为'null'
Optional empty = Optional.ofNullable(null);
isPresent:
如果值存在返回 true, 否则返回 false
//ifPresent方法接受lambda表达式作为参数。
//lambda表达式对Optional的值调用consumer进行处理。
name.ifPresent((value) -> {
System.out.println("The length of the value is: " + value.length());
});
ofNullable
: 为指定的值创建一个 Optional, 如果指定的值为 null, 则返回一个空的 OptionalorElse
: 如果Optional实例有值则将其返回,否则返回orElse方法传入的参数
user = Optional.ofNullable(user).orElse(new User());
// 上一行代码 等价于 下一行代码
user = (user == null) ? new User() : user;
orElse 和 orElseGet 的区别
当 Optonal 的值是空值时, 无论 orElse 还是 orElseGet 都会执行; 而当返回的 Optional 有值时, orElse 会执行, 而 orElseGet 不会执行。 因此, orElseGet 方法在性能上要优于 orElse 方法
orElseGet可以接受一个lambda表达式生成默认值
//输出:Default Value
System.out.println(empty.orElseGet(() -> "Default Value"));
//输出:Sanaulla
System.out.println(name.orElseGet(() -> "Default Value"));
map
: 如果有值, 则对其执行调用 mapping 函数得到返回值。 如果返回值不为 null, 则创建包含 mapping 返回值的 Optional 作为 map 方法返回值, 否则返回空 Optionalfilter
: 如果有值并且满足断言条件返回包含该值的 Optional, 否则返回空 Optional
RltData data = new RltData("20191008125000", new BigDecimal(10000), (byte)1);
Result result = new Result(10, data);
Response response = new Response(1000, "success", result);
String rlt = checkRlt(response);
System.out.println(rlt);
private static String checkRlt(Response response) {
return Optional.ofNullable(response)
.map(Response::getResult)
.map(Result::getData)
.map(RltData::getOrderNo).orElse("none");
}
注意事项
Optional 是一个 final 类,未实现任何接口,Optional 不能序列化,不能作为类的字段
可以通过自己实现 getter 方法,使 Lomok 不自动生成
Java 14 Helpful NullPointerExceptions
<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