美文网首页JAVA
单纯的使用Optional并不能很好的解决业务中的NPE问题

单纯的使用Optional并不能很好的解决业务中的NPE问题

作者: PageThinker | 来源:发表于2019-12-14 16:56 被阅读0次

    工作中经常会遇到NPE(NullPointException)问题怎么处理,得到最多的回答就是Optional来处理,但是单纯的使用Optional并不能很好的解决业务中的NP问题。所以整理出日常工作中处理NPE问题的思路,供参考。

    先看一下思路:

    解决NPE的思路

    01 避免的操作

    01.01 避免入参使用 Optional

    日常工作中有是看到如下代码。

    public void execute(Optional<String> nameOptional) {
       ...
    }
    

    如果方法的某个参数可能为null,那么可以使用方法重载,而不是传入一个null。因为代码的实现上揭示业务意图要要好于只表示业务意图,因为在业务上null没有业务意义,如果出现null,而又需要处理相关逻辑,那么可以使用方法重载。

    另外,方法调用者将很清晰起作用的参数,也不需要为了调用某个方法而构造Optional。

    public void execute() {
         execute(null);
    }
    
    public void execute(String name) {
        ...
    }
    

    上面的代码避免了对外方法的意图模糊,同时也避免了部分的重复代码。

    01.02 避免多行 if() 语句

    “使用了Optional,也没有感觉逻辑变变简单啊,每次都得get()方法”,这是工作中听到的刚刚接触Optional的开发人员的表述。

    问题在哪里呢?如果我们有一把把核桃夹子,但是每次用这把核桃夹子做的事情都是砸核桃,那么就发现和用锤子砸也没有什么区别,结果都是碎了一地。

    我们都说代码时重构出来的,而不是设计出来的。所以实现的时候如果对Optional不熟悉可以使用if来判断,重构的时候可以试着寻找一些能够有更好的解决办法。因为switch语句本来就是坏味道,寻找的方向可以先看看Optional除了提供了get方法,还提供了哪些方法,它们都是做什么用途的。

    02 如何做

    02.01 使用返回值中用Optional显式处理

    如果实际实现中需要我们将null值返回,我们可以return一个Optioanl对象回去,这样该方法的调用者就必须就知道返回中有可能为null,并对其进行特定的处理。

    public Optional<Data> execute() {
        ...
        return Optional.empty();
    }
    

    02.02 适当的时候使用Exception

    并不是找不到结果我们就只能选择返回Optiona.empty(),除非逻辑需要继续执行而不期望中断,否则我们可以直接选择抛出异常。

    例如,根据username、password寻找用户的方法,如果找不到用户,可以直接抛出InvalidUsernameOrInvalidPasswordException。

    public User login(String name, String password) {
        ...
        
        throw new InvalidUsernameOrInvalidPasswordException();
    }
    

    那么,外层要么进行异常处理,要么Project进行全局异常捕获,统一进行处理。

    02.03 使用Optional Lambda

    在01.02中提到了因为对Optional提供的方法不熟悉,而感觉和null值判断没有多大区别。那么推荐根据业务场景来选择Optioanl Lambda的写法。

    String name = computer.flatMap(Computer::getSoundcard)
        .flatMap(Soundcard::getUSB)
        .map(USB::getVersion)
        .orElse("UNKNOWN");
    

    上面写法要比下面的写法清晰很多。当然这需要保持好奇心,多学习一点工具类提供的方法,同时别总是制作简单的搬砖工作。

    String version = "UNKNOWN";
    if (computer != null) {
        Soundcard soundcard = computer.getSoundcard();
        if (soundcard != null) {
            USB usb = soundcard.getUSB();
            if (usb != null) {
                 version = usb.getVersion();
            }
        }
    }
    

    参考


    02.03最终的代码来源

    相关文章

      网友评论

        本文标题:单纯的使用Optional并不能很好的解决业务中的NPE问题

        本文链接:https://www.haomeiwen.com/subject/quthnctx.html