作者:l 拉不拉米 \
链接:https://juejin.cn/post/703144…
一、前言
Hello 大家好,我是 l 拉不拉米
,明天带来一个实在案例,让大家更粗浅的了解 空指针异样
。
公司刚入职了一名 中级 Java 开发
,通过一个星期的适应学习,各方面体现还不错,于是调配了一个小的迭代给新人做。
需要很简略,把从第三方拉取的数据匹配到本身公司后盾设置的渠道后,聚合到一个列表中,批量入库。
然而就在匹配的逻辑中,上线后报了个 NPE,这是作为一名中级开发不应犯的简略谬误,新人被我 狠狠的训了
,记生产事变一次。
二、事变重现
伪代码
阐明
:伪代码并非实在线上代码,只是为了更不便,更形象的重现事故现场而编写的;实在的业务场景往往更加简单,NPE 的破绽暗藏在更深处,不易 code view 进去,也不易测试进去;生产环境 NPE 是较常见的异样,心愿大家不要纠结为什么测试没测进去,要害还是通过这样一个案例理解 NPE 的起因和解决方案。
// 后盾设置的渠道
String channelNo = channelDao.getOne().getChannelNo();
// 第三方拉取的数据
List<ThirdData> thirdDataList = httpClientUtils.getThirdDatas(DateUtils.today());
// 匹配过滤
thirdDataList.stream().filter(o ->channelNo.equals(o.getChannelNo())).collect(Collectors.toList());
// 批量入库
thirdDataDao.saveAll(thirdDataList);
举荐一个开源收费的 Spring Boot 最全教程:
https://github.com/javastacks/spring-boot-best-practice
剖析与解决
有教训、技术扎实的同学看到这里应该或多或少能发现问题了。其实啊,这四段代码是作者精心设计的,堪称是 卧龙凤雏😀😀。
短短 四行代码
竟然凑齐了 3 个 NPE,我枯了 /(ㄒ o ㄒ)/~~
咱们逐行剖析:
第一行剖析
channelDao.getOne()如果返回为 null,那么调用 getChannelNo()会报NPE
。
解决办法
1、应用防御性编程,提前返回(需依据具体业务场景而定)
// 如果 channelNo 是办法逻辑执行的必须元素,举荐用此办法
Channel channel = channelDao.getOne();
if (channel == null) {return;}
2、应用三目运算,返回空字符串(””)
// 返回兜底的空字符串
String channelNo = channelDao.getOne() == null ? "" : channelDao.getOne().getChannelNo();
3、应用 Optional 函数,返回空字符串(””)
String channelNo = Optional.ofNullable(channelDao.getOne()).orElse("");
第三行剖析(1)
thirdDataList 如果为 null,那么调用 stream()会报NPE
。
通过上面的源码截图就能晓得起因:
解决办法
1、应用防御性编程,提前返回(举荐)
// 举荐应用汇合工具类判空
if (CollectionUtils.isEmpty(thirdDataList)) {return;}
2、应用 if 条件语句包裹(不举荐)
if (CollectionUtils.isNotEmpty(thirdDataList)) {// 执行前面的逻辑}
第三行剖析(2)
channelNo 如果返回为 null,那么执行 channelNo.equals(o.getChannelNo())会报NPE
。
咱们晓得,按 Java 的标准 String 的 equals()办法的调用,要求右边是确定值,就是为了防止调用方为 null 的状况。然而这里调用方和 equals 的入参都是变量,这种状况该怎么办呢?
1、再加一句判断:
channelNo != null && channelNo.equals(o.getChannelNo())
2、其实能够用 java.uti
包下的 Objects
类的 equals 办法
Objects.equals(channelNo, o.getChannelNo())
看源码高深莫测,该办法对右边的对象做了非空判断
3、用其余开源的工具类库或者本人实现
如:
org.apache.commons.lang3.StringUtils
cn.hutool.core.util.StrUtil;
最初
在这里 l 拉不拉米
要举荐一款 IDEA 的插件:
SonarLint
能动静的帮您查看代码破绽,像 NPE 这种代码危险都会给于相应的提醒。
SonarLint 还有一个赫赫有名的服务端叫SonarQube
。
近期热文举荐:
1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)
2. 劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!