前言:
根据在公司开发的过程中经常出现的低级但风险比较高的问题进行了整理,最常见的就是将动态SQL查询到的结果放到一个list里面,然后进行轮训再get取值,经常出现要么动态SQL没有查询到结果,要么get取值的时候没取到值,这个时候就会出现程序出现异常报空指针(java.long.NullPointException),尤其是因为给银行开发核心系统,一个空指针报错就可能导致账务发生很大的变动(又娇贵又顽强)
工作场景:
由图可知,日志中可以看到交易中报错空指针!原因就是因为动态SQl未查询到结果导致代码中取值的时候未取到值报的错,最常见的方式就是先对查出来的结果进行非空判断,如果有值才能进行get或set操作。
例如:
Massage massage = fjyhtytfcgf.sel_gdsy_nbsjd(nbhg, jdjhfg,false);
//当查询结果不为空时才能进行取值或者赋值。
if(XXX.isNotNull(Massage)){
Massage.setsgfsfd(Massage.getfghdfg());
Massage.setmiokm(Massage.getjgvff());
}
简单的举个栗子!!!
对于面向对象而言,抽象层级真的是重中之重了!尤其是现在金融行业,银行核心系统大量的交易,数以万计的接口,在设计和开发中占的比重真的很大,因为这样会很方便,所以我们自己在开发的时候尽可能的面向接口进行编程。
栗子来了:存在一个UserService用来提供客户查询的功能:
public interface UserService {
List<User> listUser();
User get(Integer id);
}
问题来了奥:由上面的描述可以看到,能判断出可能他包含了以下两个含义:
1、listUser():用于查询列表
2、get(Integer id):用于查询单个用户
在所有的开发中,XP推崇的TDD模式可以很好的引导我们对接口的定义,所以我们将TDD作为开发代码的推动者。
对于以上的接口,当我们使用TDD进行测试用例时发现,能看出来潜在的问题:
1、listUser()如果没有数据,那么他返回的是空集合还是null呢?
2、get (Integer id)如果这个对象不存在,那么是抛出异常还是返回null呢?
深入研究listUser
我们一步步的看奥,先来讨论listUser。
这个接口,经常可以看到如下实现:
public List<User> listUser(){
List<User> userlist = UserListRepostity.selectByExample (new UserExample ());
//使用spring 的 util工具类
if(CollectionUtils.isEmpty(userList)){
return null;
}
return userlist;
}
这段代码返回是null,根据实际场景来说,对于这样的集合返回值,最好不要返回一个null,因为如果返回了null,会给调用的人带来很多麻烦,你可能会把这种调用风险交给调用者来控制。
如果调用者是一个谨慎的人,那么他会进行是否为null的判断,如果不谨慎,那么他肯定会按照自己的理解去及逆行调用,肯定不会判空,如果这样的话,那就有危险了,很可能会出现空指针。
基于这个,我们将它进行一下代码优化操作:
public List<User> listUser(){
List<User> userlist = UserListRepostity.selectByExampl