目录
1、问题背景
在项目中我们经常遇到空指针异常,为了防止该异常发生,我们往往需要加一大堆的判断,来防止对象是null的场景。
2、判空举例
比如下面这几个对象
public class Person {
private Car car;
public Car getCar() { return car; }
}
public class Car {
private Insurance insurance;
public Insurance getInsurance() { return insurance; }
}
// 保险公司
public class Insurance {
private String name;
public String getName() { return name; }
public void setName(String name) {this.name = name;}
}
如果给定一个Person对象,想要获取对应保险公司的名称,那么为了防止空指针异常的出现,我们往往会这么获取,每次引用一个变量都会做一次null检查、if嵌套层数多,代码膨胀
public String getCarInsuranceName(Person person) {
if (person != null) {
Car car = person.getCar();
if (car != null) {
Insurance insurance = car.getInsurance();
if (insurance != null) {
return insurance.getName();
}
}
}
return "unknown";
}
3、用Optional取代判空
首先看下几个关于Optional常用方法:
(1)Optional.ofNullable():创建一个可接受null的Optional对象
比如Optional<Person> optPerson = Optional.ofNullable(persion)
(2)map():从Optional对象中提取和转换值
比如Optional<Car> optCar = optPerson.map(Person::getCar)
(3)orElse():当Optional对象中存储的值不存在时,返回一个默认值
针对这种冗余判空操作,可以使用Optional来替代
public static String getCarInsuranceName(Person person) {
return Optional.ofNullable(person).map(Person::getCar)
.map(Car::getInsurance)
.map(Insurance::getName)
.orElse("unkown");
}
4、两个Optional对象组合
假设有这样一个方法,它接受一个Person和一个Car对象,并根据这两个对象通过一些复杂的业务计算,返回一个最便宜的保险公司:
public Insurance findCheapestInsurance(Person person, Car car) {
// 复杂计算逻辑省略
return new Insurance();
}
为了防止空指针异常,我们往往会这么写
public Insurance findCheapestInsuranceSafe(Person person, Car car) {
if (person != null && car != null) {
return findCheapestInsurance(person, car);
}
return new Insurance();
}
其实也可以通过两个Optional封装后,用一行代码实现
public Insurance findCheapestInsuranceSafe1(Person person, Car car) {
return Optional.ofNullable(person).flatMap(p -> Optional.ofNullable(car).map(c -> findCheapestInsurance(p, c))).orElse(new Insurance());
}