小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
Java8 新特性中包括了Stream相关的操作,由于是流式编程,在项目中使用时十分方便。但是,流式操作的过程中,当中间的结果对象有存在为null的可能时,整个流式操作进行时就会报出空指针异常。
1. NullPointerException
NullPointerException,即空指针(引用)异常,是一种运行时异常,在对一个null对象进行相关属性或方法调用时产生,会导致程序运行异常。
在项目开发的业务处理中,处理最多的异常基本就是空指针异常,空指针异常的适当处理能够让项目更加稳定。
本文主要讲解在Java8流式操作中如何优雅的处理NullPointerException。
2. Java8中处理NullPointerException
现有的业务场景中存在订单和产品类:Order、Product,其关系如下所示:
public class Production {
private Integer productionId;
private String productName;
private ProductSpecification productSpec;
}
public class ProductSpecification {
private Integer productSpecId;
private String productSpecName;
}
2.1 Java8之前业务逻辑处理
如果我们需要从订单中获取指定商品的信息,则需要有操作:
//判断条件复杂
public String getSpecName(Product product) {
if (product != null && product.getSpec != null) {
return product.getSpec.getSpecName();
}else {
return "";
}
}
//逻辑臃肿
public String getSpecName(Product product) {
if (product != null) {
Specification spec = product.getSpec;
if (spec != null) {
return spec.getSpecName();
} else {
return "";
}
}else {
return "";
}
}
可以看出我们在对一个对象进行操作时,需要对操作过程涉及到的对象进行判空操做,大量的判空操作和if..else导致代码十分臃肿。
2.2 Java8操作展身手
针对频繁的判空操作和代码臃肿问题,我们可以使用Java8的Stream流式操作来实现对象取值。
public void print(Product product){
Optional.ofNullable(production)
.map(Production::getProductSpec)
.ifPresent(specInfo -> System.out.println(specInfo.getSpecName()));
}
这一段代码的逻辑可以理解为:
- 如果production为null,则返回空的Optional对象并不输出任何值
- 如果production不为null,则通过getProductSpec方法获取production中的productSpec属性
- 如果productSpec属性存在,则输出其productSpecName值。
2.3 Optional
Optional是Java8新加入的容器,这个容器中有1个或者0个元素,Optional的出现就是用来防止NullpointException的。常见的方法有:
- Optional.empty():创建一个空的Optional实例
- Optional.of(T t) : 创建一个Optional 实例,为null时报异常
- Optional.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
- isPresent() : 判断容器中是否有值
- ifPresent(Consume lambda) :容器若不为空则执行括号中的Lambda表达式
- orElse(T t) : 获取容器中的元素,若容器为空则返回括号中的默认值
- orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
- map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
- flatMap(Function mapper):与map 类似,要求返回值必须是Optional
- T get() :获取容器中的元素,若容器为空则抛出NoSuchElement异常
3. 总结
Java8流式操作增加了诸多的便利性,但是在普通的流式操作使用时仍然会存在NullPointerException,因此在实际项目的业务处理逻辑中还要需要多考虑,减少异常对系统稳定的影响。
Optional作为新增加的用于优雅的处理NullPointerException,其中提供了很多方法都对null进行了判断,是一种很合适对象操作方法。
本篇文章仅作为Optional入门学习,开启新大门的钥匙,在之后的日子里不断的深入学习。
Java都16了,Java8还不快掌握起来啦!