使用Java 8 的 Optional 类进行优雅的判空

你是否曾经被 NullPointerException 异常折磨的苦不堪言?你是否曾为复杂的POJO 类写非空判断,为那多个 if xxx != null 或多层嵌套 if xxx != null 的代码感到烦恼心累?

呐,程序猿们,我们是时候用Java 8 的 Optional 类进行优雅的判空啦,当然,如果你用的是 Java 8 的话(:з」∠)。

Optional 是什么?
java.util.Optional 类是 Java 8 引入的一个新的类,是一个容器,可以保存类型为T的值,也可以保存null值,它提供了许多有用的方法,使得我们可以不用显示进行空值检查。

Optional 的类方法
方法 描述

  1. static Optional empty() 返回一个空的 Optional 实例
  2. static Optional of(T value) 返回一个包含指定 value 的Optional,如果 value 为空,则抛出 NullPointerException
    static Optional ofNullable(T value) 将指定的值用 Optional 封装之后返回,如果 value 为null,则返回一个空的 Optional 对象
  3. T orElse(T other) 如果 Optional 有值,则将其返回,否则返回指定 other 值
  4. T orElseGet(Supplier<? extends T> supplier) 如果 Optional 有值则将其返回,否则返回一个由指定的Supplier 接口生成的值
  5. T orElseThrow() 如果 Optional 有值,则将其返回,否则抛出 NoSuchElementException 异常
  6. T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X 如果 Optional 有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常

上面基本上列出了 Optional 类的所有方法,下面挑几个常用的方法进行介绍:

public class  {

    
    @AllArgsConstructor
    @NoArgsConstructor
    private static class Basket {
        private Apple apple;
    }

    
    @AllArgsConstructor
    @NoArgsConstructor
    private static class Apple {
        private String color;

        private Double weight;
    }

    public static void main(String[] args) {
        Apple apple = new Apple("red", 20.00);
        Basket basket = new Basket(apple);
        try {
            
            Optional<Apple> optionalApple1 = Optional.of(apple);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        // 将 apple 用 Optional 封装之后返回,如果 apple 为null,则返回一个空的 Optional 对象
        // 推荐采用这种方式
        Optional<Apple> optionalApple2 = Optional.ofNullable(apple);

        try {
            // 如果 optionalApple 包含有值,则返回该值,否则抛出 NoSuchElementException 异常
            Apple apple1 = optionalApple2.get();
        } catch (NoSuchElementException e) {
            e.printStackTrace();
        }

        // 如果不想get()抛出异常,可以使用 orElse() 方法
        // 如果 optionalApple2 有值,则将其返回,否则返回指定 null 值
        Apple apple1 = optionalApple2.orElse(null);

        // 如果 optionalApple2 有值存在,就对该值执行提供的mapping 函数调用
        Optional<Double> weightOptional = optionalApple2.map(Apple::getWeight);

        // 可以与 get() 一起使用,或者与 orElse() 一起使用
        Double weight1 = optionalApple2.map(Apple::getWeight).get();
        Double weight2 = optionalApple2.map(Apple::getWeight).orElse(00.00);

        // 从 Basket 中 获取 Apple 的 weight
        Double appleWeight1 = Optional.ofNullable(basket)
                .map(Basket::getApple)
                .map(Apple::getWeight)
                .orElse(00.00);

        // 使用 orElseThrow
        Double appleWeight2 = Optional.ofNullable(basket)
                .map(Basket::getApple)
                .map(Apple::getWeight)
                .orElseThrow(NullPointerException::new);
    }
}

使用 Optional 进行优雅判空
还是用上面列举的类,如果不用使用 Optional,想要获取 Basket 类内的 Apple 类的 weight 值,得这样写:

public double getAppleWeight(Basket basket){
    if (basket != null){
        Apple apple = basket.getApple();
        if (apple != null){
            Double weight = apple.getWeight();
            if (weight != null){
                return weight;
            }
        }
    }
    return 0.0;
}

看看这个 if 嵌套,emm…,这还是较为简单的 pojo 类,如果是复杂的,简直不堪入目啊。
而在 Optional 的加持下,只需这样写:

public double getAppleWeight(Basket basket){
    return Optional.ofNullable(basket)
            .map(Basket::getApple)
            .map(Apple::getWeight)
            .orElse(0.0);
}

瞬间代码就清爽了,嘻嘻,人也跟着欢快起来了。

当然 Optional 不止能进行优雅的判空,还可以利用 Optional 的其它的API,进行一些神奇的操作,比如使用 filter 进行参数校验之类的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值