zoukankan      html  css  js  c++  java
  • java8 用Optional取代null

    如何处理null

    怎样做才能避免不期而至的NullPointerException呢?通常,可以在需要的地方添加null的检查(过于激进的防御式检查甚至会在不太需要的地方添加检测代码),并且添加的方式往往各有不同。

    null-安全的第一种尝试:深层质疑

     “深层质疑”,原因是它不断重复着一种模式:每次不确定一个变量是否为null时,都需要添加一个进一步嵌套的if块,也增加了代码缩进的层数。很明显,这种方式不具备扩展性,同时还牺牲了代码的可读性。

    null-安全的第二种尝试:过多的退出语句

     第二种尝试中,试图避免深层递归的if语句块,采用了一种不同的策略:每次遭遇null变量,都返回一个字符串常量“Unknown”。然而,这种方案远非理想,现在这个方法有了四个截然不同的退出点,使得代码的维护异常艰难。

    使用Optional获取car的Insurance名称

    汲取Haskell和Scala的灵感,Java 8中引入了一个新的类java.util.Optional<T>。这是一个封装Optional值的类。

    public String getCarInsuranceName(Optional<Person> person){
        return person.flatMap(Person::getCar)
            .flatMap(Car::getInsurance)
            .map(Insurance::getName)
            .orElse("Unknown");//如果Optional的结果值为空,设置默认值
    }

    创建Optional对象

    1. 声明一个空的Optional

    可以通过静态工厂方法Optional.empty,创建一个空的Optional对象:

    Optional<Car> optCar = Optional.empty();

    2. 依据一个非空值创建Optional

    还可以使用静态工厂方法Optional.of,依据一个非空值创建一个Optional对象:

    如果car是一个null,这段代码会立即抛出一个NullPointerException,而不是等到试图访问car的属性值时才返回一个错误。

    Optional<Car> optCar = Optional.of(car);

    3. 可接受null的Optiona

    使用静态工厂方法Optional.ofNullable,可以创建一个允许null值的Optional对象:

    如果car是null,那么得到的Optional对象就是个空对象。

    Optional<Car> optCar = Optional.ofNullable(car);

    Optional类的方法

     •null引用在历史上被引入到程序设计语言中,目的是为了表示变量值的缺失。   

    •Java 8中引入了一个新的类java.util.Optional<T>,对存在或缺失的变量值进行建模。   

    •可以使用静态工厂方法Optional.empty、Optional.of以及Optional.ofNullable创建Optional对象。   

    •Optional类支持多种方法,比如map、flatMap、filter,它们在概念上与Stream类中对应的方法十分相似。   

    •使用Optional会迫使更积极地解引用Optional对象,以应对变量值缺失的问题,最终,能更有效地防止代码中出现不期而至的空指针异常。   

    •使用Optional能帮助设计更好的API,用户只需要阅读方法签名,就能了解该方法是否接受一个Optional类型的值。

    附:类代码

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

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

    public class Person {
        private Optional<Car> car;//人可能有车,也可能没有车,因此将这个字段声明为Optional
    
        public Optional<Car> getCar() {
            return car;
        }
    }
    
    public class Car {
        private Optional<Insurance> insurance;//车可能进行了保险,也可能没有保险,所以将这个字段声明为Optional
    
        public Optional<Insurance> getInsurance() {
            return insurance;
        }
    }
    
    public class Insurance {
        private String name;//保险公司必须有名字
    
        public String getName() {
            return name;
        }
    }

    文章来源:java8实战 第十章

  • 相关阅读:
    linux 中$ 意思
    Linux查看日志命令- more、less、tail、head命令的区别
    center os 创建用户、设置密码、修改用户、删除用户命令
    Hello world
    小程序3.6
    小程序3.5
    小程序3.4
    小程序2
    小程序
    事件冒泡
  • 原文地址:https://www.cnblogs.com/ooo0/p/11469391.html
Copyright © 2011-2022 走看看