optional 可以避免null,在使用 optional 前看下下面的例子:
//保险
public class Insurance {
private String name;
public String getName() {
return name;
}
}
public class Car {
private Insurance insurance;
public Insurance getInsurance() {
return insurance;
}
}
public class Person {
private Car car;
public Car getCar() {
return car;
}
}
定义了三个类,Person Car Insurance ,它们三者关系为 Person -> Car -> Insurance ,现在定义一个方法获取保险名称,如下:
public class OptionalTest01 {
public static String getCarInsuranceName01(Person person){
return person.getCar().getInsurance().getName();
}
public static void main(String[] args) {
Person person = new Person();
getCarInsuranceName01(person);
}
}
毫不出意外,程序抛出空指针异常:
Exception in thread "main" java.lang.NullPointerException
at com.hs.example.base.jdk8.optional.OptionalTest01.getCarInsuranceName01(OptionalTest01.java:6)
at com.hs.example.base.jdk8.optional.OptionalTest01.main(OptionalTest01.java:11)
如何避免程序抛出异常,当有空对象时让方法输出默认值,比较直接的方法便是使用 if 判断:
public static String getCarInsuranceName02(Person person) {
if (person != null) {
Car car = person.getCar();
if (car != null) {
Insurance insurance = car.getInsurance();
if (insurance != null) {
return insurance.getName();
}
}
}
return "";
}
这种方法嵌套太多,影响程序可读性,也可使用如下方法:
public static String getCarInsuranceName03(Person person) {
if (person == null) {
return "";
}
Car car = person.getCar();
if (car == null) {
return "";
}
Insurance insurance = car.getInsurance();
if (insurance == null) {
return "";
}
return insurance.getName();
}
显然这种方式也不好,return “” 同一段代码出现次数太多,
如下:仅用一行代码就可以避免 空指针异常并返回默认值
public static String getCarInsuranceName04(Person person) {
return Optional.ofNullable(person).map((person1 -> person1.getCar())).map((car -> car.getInsurance())).map(insurance -> insurance.getName()).orElse("");
}
如下 Optional 类包含一个泛型参数 T ,
public final class Optional {
/**
* Common instance for {@code empty()}.
*/
private static final Optional> EMPTY = new Optional<>();
/**
* If non-null, the value; if null, indicates no value is present
*/
private final T value;
private Optional() {
this.value = null;
}
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;
return t;
}
}
通过 ofNullable 方法初始化一个 Optional 对象,当 value(对应上例中 Person,Car 等对象) 为空时返回 EMPTY Optional,
public static Optional ofNullable(T value) {
return value == null ? empty() : of(value);
}
上面一行代码可以分解成这样:
public static String getCarInsuranceName05(Person person) {
Optional personOptional = Optional.ofNullable(person);
Optional carOptional = personOptional.map((person1 -> person1.getCar()));
Optional insuranceOptional = carOptional.map((car -> car.getInsurance()));
Optional nameOptional = insuranceOptional.map(insurance -> insurance.getName());
return nameOptional.orElse("");
}
public Optional map(Function super T, ? extends U> mapper) {
// 校验 mapper是否为 null ,为 null 直接抛出空指针异常
Objects.requireNonNull(mapper);
// 当前 optional 对象 属性value是否为null,为空返回 EMPTY Optional
if (!isPresent())
return empty();
else {
// 调用 函数式方法(对应上例中 person1.getCar() ),返回 Car 的 Optional 对象
return Optional.ofNullable(mapper.apply(value));
}
}
isPresent 方法
public boolean isPresent() {
return value != null;
}
如上:map方法接收参数为 函数式方法
@FunctionalInterface
public interface Function {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
对应上例中 Optional nameOptional 的 nameOptional.orElse(“”) 方法,如果 name 不为空则返回 name ,否则返回 “”
public T orElse(T other) {
return value != null ? value : other;
}
例子引用自 Java8 实战第10 章