本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
让开,我要开始装逼了。因为 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 异常。
这一点,我们也可以从 Long 重写的 equals 方法上看出问题。
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
而实际上,在《阿里巴巴Java 开发手册》中,已经有了明确的强制性要求了。虽然说和我们这一个有些差异,但也是也可以借鉴的。
最后,一定要注意。用==比较包装类型和非包装类型的时候,包装类型对象被拆箱(转为非包装的基本类型)。
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » 3个程序员都没解决掉的一个包装类型和非包装类型的NULL异常