设为首页 加入收藏

TOP

Java 8新特性之Optional取代null(一)
2018-11-20 22:09:42 】 浏览:710
Tags:Java 特性 Optional 取代 null

NullPointerException,大家应该都见过。这是Tony Hoare在设计ALGOL W语言时提出的null引用的想法,他的设计初衷是想通过编译器的自动检测机制,确保所有使用引用的地方都是绝对安全的。很多年后,他对自己曾经做过的这个决定而后悔不已,把它称为“我价值百万的重大失误”。它带来的后果就是---我们想判断一个对象中的某个字段进行检查,结果发现我们查看的不是一个对象,而是一个空指针,他会立即抛出NullPointerException异常。


看下面这个例子:


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 String getCarInsuranceName(Person p){
        return p.getCar().getInsurance().getName();
    }


这是一个获取保险公司名字的方法,但是在库里可能很多人没有车,所以会返回null引用。更没有车险,所以直接返回一个NullPointerException。


为了避免这种情况,我们一般会在需要的地方添加null的检查,并且添加的方式往往不同。


 


避免NullPointerException第一次尝试:


 


    public String getCarInsuranceName(Person p){
        if(p != null){
            Car car = p.getCar();
            if(car != null){
                Insurance insurance = car.getInsurance();
                if(insurance != null){
                    return insurance.getName();
                }
            }
        }
        return "Unknown";
    }


 


 这个方法每次引用一个变量时,都会做一次null检查,如果任何一个返回值为null,则会返回Unknown。因为知道公司都必须有名字,所以最后一个保险公司的名字没有进行判断。这种方式不具备扩展性,同时还牺牲了代码的可读性。每一次都要嵌套一个if来进行检查。


 


避免NullPointerException第二次尝试:


 


    public String getCarInsuranceName(Person p) {
        if (p == null) return "Unknown";
        Car car = p.getCar();
        if (car == null) return "Unknown";
        Insurance insurance = car.getInsurance();
        if (insurance == null) return "Unknown";
        return insurance.getName();
    }


 


第二种方式,避免了深层if语句块,采用了每次遇到null都直接返回Unknown字符串的方式。然后这个方案也并非理想,现在这个方法有了四个截然不同的退出点,使代码的维护更艰难。发生null时的默认值,在三个不同的地方出现,不知道具体是哪个返回null。


 


Optional类


  Java 8中引入了一个新的类java.util.Optional<T>。这是一个封装Optional值的类。当变量存在时,Optional类知识对类简单封装,变量不存在时,缺失的值被建模成一个空的Optional对象,由方法Optional.empty()返回。该方法是一个静态工厂方法,返回Optional类的特定单一实例。


  null和Optional.empty()从语义上,可以当做是一回事。实际上它们之间的差别非常大:如果你尝试访问一个null,一定会触发null引用。而Optional.empty()可以在任何地方访问。


 


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;
    }
}


 


公司的名字我们没有使用Optional<String> 而是保持了原类型String,那么它就必须设置一个值。


 


创建Optional对象


  1.声明一个空的Opt

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java 8新特性之新的日期和时间API 下一篇Python反射机制详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目