欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

提高java8编写代码,出现null异常可以用使用Optional类

程序员文章站 2022-06-07 12:34:08
...

java8 增加了2个API入手

Optional类

java 9 对日期和时间Api进行改进,已经文档化和可执行方式的模块化

 

用Optional取代null

我想每个java开发人员,都会遇到这个异常,NullPointerException 空指针异常;如果没有遇到的请举手,有时候修复Null的代价是很高的。

如何为缺失的值建模

如:建设有个汽车和汽车保险的客户,可以用户,商品,订单等其他模型

person / car / insurance的数据模型

建立模型

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 persion / Insurance insurance / String name 定义的时候,全部是定义的null,如果直接调用

getXXXX方法 (getPerson,getInsurance,getName)3个方法,会返回常见的null引用。

采用防御是检测减少NullPointerException,通过判断person ==null 或者是name==null 或者是 Insurance ==null

代码可能是这样的

public String getCarInsuranceName(Person person)
{

    if (person!=null){

        Car car =person.getCar();
        if (car!=null){
            Insurance in = car.getInsurance();
            if (in !=null){
                return in.getName();
            }
        }
    }
    return "unknown";


}

上面这种方式每次引入一个变量都需要判断一下null检测,如果引用链上的任何一个遍历的解遍历为null,它就返回unknown,唯一例外的是保险公司的名称,不需要检测,因为必定会有名称。上述代码会有一个很大的问题,就是每次都要不断的重复进行检测null,如果增加一个新的属性,又要嵌套一层if语句,代码不容易扩展。或者我们可以不用嵌套if判断,用if 语句平行判断呢?

public String getCarInsureanceName(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();
}

第二种虽然避免了第一种的if的嵌套的,但每次碰到null 都返回unknow。如果有方法调用这个类,返回unkown 都不知道是哪个类为空,不利于维护异常。

null带来了种种问题

  • 错误之源
  • 会让代码膨胀
  • 它自身毫无意义

其他语言的null的替代品Groovy

def carInsuranceName = person?.car?.insurance?.name

这段代码非常清晰,person对象可能没有car对象。Croovy的安全导航操作符避免了null引用空指针异常。

 

java8 出现Option的值

引入Optional<T>的新类。如何在你的领域模型下用Optional值

可以这样使用Optional<Car> 或者是Optional<insurance>

使用了Optional定义的Car类和使用了Optional的Insurancel类

Optional有个empty()返回

在java8 里面可以把在java7的代码改写一下使用Optional类

public class Person {

    private Optional<Car> car;
    public Optional<Car> getCar(){
        return car;
    }

}

public class Car{

    private Optional<Insurance> insurance;
    public Optional<Insurance> getInsurance(){
    
        return insurance;
    }

}

public class Insurance{

    private String name;
    public String getName(){return name;}


}

分别定义了2个Optional的数据模型Car和Insurance。

使用Optional类的意图并不是消除每个的null引用。它的目的是帮助我们更好的设计出普适的API

 

 

相关标签: spring实践大全