文章目录
一、Java 8 为什么引入Optional类?
null在Java中是一个合法值,目的是为了表示变量值的缺失。但对null的引用会引起NullPointerException(空指针异常)。在Java8以前,Java程序员操作对象时,为了避免错误引用null造成的空指针异常,往往需要一系列繁杂冗余的判空操作,增加了许多重复代码,降低了代码可读性,于是Java 8 引入Optional,优雅简洁的对null值进行处理。
为了便于理解和说明,本文将用以下的模型进行讲解:
假设有以下嵌套对象:人持有车,车持有保险,保险有名字属性。
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; }
}
假设要获取某一Person对象的车的保险的名字:
public String getCarInsuranceName(Person person) {
return person.getCar().getInsurance().getName();
}
上面代码看似正常,但实际情况是getCar()和getInsurance()方法都可能返回null值,导致后续引用引起空指针异常。
Java 8 以前是怎么处理以保证null安全的呢:
1) 过多的 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";
}
或者:
2)过多的 return语句:
public String getCarInsuranceName(Person person) {
if (person == null) {
return "Unknown";
}
Car car = person.getCar();
if (car == null) {
return "Unknown";
}
Insurance insurance = car.getInsurance();
if (insurance == null) {
return "Unknown";
}
return insurance.getName();
}
接下来让我们进入下一章,了解Optional类,看看Optional类是怎样处理上述情形的。
二、什么是Optional类?
Java 8 中引入了一个新的类java.util.Optional<T>。可以理解为这是一个封装普通类对象(包括空值null)的容器类,Optional 对象最多只包含一个值。举例说明:
如果你知道一个人可能有也可能没有车,那么Person类内部的car变量就不应该声明为Car,当某人没有车时把null引用赋值给它,而是应该像下图那样直接将其声明为Optional<Car>类型。变量存在时,Optional类只是对类简单封装。变量不存在时,缺失的值会被建模成一个“空” 的Optional对象,由方法Optional.empty()返回。
使用Optional重新定义Person/Car/Insurance的数据模型:
public class Person {
// 人可能有车,也可能没有车,因此将这个字段声明为Optional
private Optional<Car> car;