• 使用Optional解决长调用链NPE问题


    使用Optional解决长调用链NPE问题

      Java NPE即Null Pointer Exception,如果一次的调用链很长,一旦中间出现了null就很难判断是哪一层为null了。(羡慕Kotlin有?.这种调用)

    举个例子,现在有一个简单的类:

    public class Simple {
        List<String[]> list;
    
        public List<String[]> getList() {
            return list;
        }
    
        public void setList(List<String[]> list) {
            this.list = list;
        }
    }
    

    我们的需求是:判断一个Simple对象的list里面的第一个String数组的第一个元素是否以“10”开头,你可能会这么写:

    public boolean checkSimple(Simple simple) {
        return simple.getList().get(0)[0].startsWith("10");
    }
    

    如果你直接这么写,那么恭喜你,不仅可能会出现空指针异常,还有可能出现数组越界异常,所以我们在调用的时候需要进行null判定:

    public boolean checkSimple(Simple simple) {
        if (simple != null) {
            List<String[]> list = simple.getList();
            if (list != null && list.size() > 0) {
                String[] strings = list.get(0);
                if (strings != null && strings.length > 0) {
                    String string = strings[0];
                    if (string != null) {
                        return string.startsWith("10");
                    }
                }
            }
        }
    
        return false;
    }
    

    我们需要去判断中间出现的每一个对象是否为null,然后才能进行下一步,非常的繁琐。

    但是如果使用Optional类则比较简洁了:

    public boolean checkSimple(Simple simple) {
        return Optional.ofNullable(simple)
                .map(simple1 -> simple.getList())
                .map(list -> list.size() > 0 ? list.get(0) : null)
                .map(strings -> strings.length > 0 ? strings[0] : null)
                .map(s -> s.startsWith("10"))
                .orElse(false);
    }
    

    不过有个缺点是写起来爽了,但是可读性还真没有if判断好。如果不熟悉这种写法的话,可能第一眼还真看不出来意图是什么。


    另外,使用Optional的时候尽量不要这么用:

    if (optional.isPresent()) {
        Object obj = optional.get();
        //do something
    }
    

    一是因为这么用和直接判空没什么区别,二是在调用get()的时候,如果其中元素为null,会直接抛出NoSuchElementException,所以尽量不要使用get()方法。

    正确的应该是这么用:

    optional.ifPresent(obj -> {
        //do something
    });
    

    用上Optional之后代码的简洁性会有提高,也更容易写出清爽干净的代码。

  • 相关阅读:
    NFS
    Linux ISO镜像挂载
    Python3.6 提示 ModuleNotFoundError: No module named '_ssl' 模块问题
    mysql 5.7 ERROR 1054(42S22) Unknown column 'password' in ‘field list’ 报错
    Redis + keepalived 高可用行配置检测脚本
    Linux 文件大小查找排序
    查看 Centos 7 的MAC 地址
    Discuz 论坛 (LAMP环境)
    SVN
    systemctl
  • 原文地址:https://www.cnblogs.com/lixin-link/p/12805089.html
Copyright © 2020-2023  润新知