3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常

让开,我要开始装逼了。因为 3 个程序员都没解决掉的一个 null 异常,被我这个第四个程序员解决了。就问你们服不服,我能解决空异常。。。

事情的起因是这样的,电商系统新版本增加了一个小功能。在发货模块有一个小需求要改动,程序员 A 更改了其中的一个方法。然后放在测试环境进行测试。这个方法时而报 NULL 异常,时而又正常。

他排查了半天,没搞定。然后依托程序员 B 前来解决,程序员 B 看了半天,没发现问题。又依托程序员 C 来解决,同样的失败了。发生车祸的代码简化如下:

try{
    long status = 0L;
    Long xttblog = null;
    System.out.println(xttblog == status);
}catch (Exception e){
    e.printStackTrace();
}

解释一下,就是有一个为 0 的状态变量 status 与一个数据库中查询出来的状态进行比较。实际代码中加上了层层的判断,!= null 的判断非常多。但是他们没想到包装类型 Long 和非包装类型 long 会出现空异常。另外一个产生这个问题的原因是,他们认为从数据库查询出来的那个 Long 不可能为空。但实际上程序员在测试过程中偷了懒,为了不删掉数据,他把需要删除的数据的主键 id 改为小于 0 的负数,最终导致了一些数据查询不出来。而调试的时候,全是正常,一到测试环境,测试一测就翻车。

上面这个代码为什么会发生空异常呢?是因为当一个包装类型和非包装类型进行 == 比较时,会进行拆箱操作。最终会转化成非包装类型进行比较,而值为 null 的包装类型 Long 在转换过程中无法正常转换就回跑出 NULL 异常。

3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常
车祸代码

这一点,我们也可以从 Long 重写的 equals 方法上看出问题。

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}

而实际上,在《阿里巴巴Java 开发手册》中,已经有了明确的强制性要求了。虽然说和我们这一个有些差异,但也是也可以借鉴的。

3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常
《阿里巴巴Java 开发手册》

最后,一定要注意。用==比较包装类型和非包装类型的时候,包装类型对象被拆箱(转为非包装的基本类型)。

3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常

: » 3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/252097.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论