【Java 8】优雅的解决空指针NullPointerException —— Optional API的详解与使用示例

一、Java 8 为什么引入Optional类?

null在Java中是一个合法值,目的是为了表示变量值的缺失。但对null引用会引起NullPointerException(空指针异常)。在Java8以前,Java程序员操作对象时,为了避免错误引用null造成的空指针异常,往往需要一系列繁杂冗余的判空操作,增加了许多重复代码,降低了代码可读性,于是Java 8 引入Optional,优雅简洁的对null值进行处理

为了便于理解和说明,本文将用以下的模型进行讲解:

假设有以下嵌套对象:人持有车,车持有保险,保险有名字属性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GCA9EtV-1633876364039)(Java8-Optional.assets/image-20210925222029200-2579657.png)]

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()返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NEaWuMLz-1633876364043)(Java8-Optional.assets/image-20210925224832661.png)]

使用Optional重新定义Person/Car/Insurance的数据模型

public class Person {
   
  	// 人可能有车,也可能没有车,因此将这个字段声明为Optional
    private Optional<Car> car; 
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值