1.返回值的空值处理
首先看一下这两个方法
// 获取所有公司
List<User> getAllCompanys();
// 获取指定id的公司
FndCompany get(Long companyId);
那么就迎来几个问题
- getAllCompanys方法 公司表如果是空的,那么返回的是空集合还是null?
- get方法 如果指定ID的公司不存在,那么返回的是空对象还是null?亦或者直接报错?
如果信息就像上面一样的话,我们对很多消息不清楚,作为一个不关心方法具体实现的调用者,有如下几种处理方式:
最稳妥的判断方式,对所有情况都进行判断
对于集合既判断null也判断Empty。
对于对象判断null,也判断是否是空对象。
显然,这种方式是没有错的,但是很繁琐,java作为一门面向对象的语言,面向接口编程的思想是贯彻始终的,作为调用者我们是不必关心具体实现的,但是这种做法变相的需要我们考虑各种可能性,失去了面向接口编程的意义。
通过接口文档注释说明
/**
* 获取所有公司
* @return 公司实体集合,为空返回空集合
*/
List<User> getAllCompanys();
/**
* 根据公司id获取公司信息
* @param companyId 公司id
* @return 公司实体
* @exception CompanyNotFoundException
*/
FndCompany get(Long companyId);
如上图,对于方法进行较为详细的说明。但是很显然,这种注释属于一种弱提示,即调用者仍然有可能不会注意,但是我们还是要养成良好的编程习惯,为每个接口方法写清楚javadoc格式的注释
开发者进行约定
对于返回值是list的方法,约定如果查出来没有数据,则返回一个空的集合而不是null,mybatis和hap的方法也是这么处理的,所以我们通常只需要处理Empty的情况即可。
对于返回值是对象的方法,则没有固定的说法,根据业务需求而定。比如,我们可以约定空数据返回值为null,也可以约定返回值为空对象(通过Optional处理),也可以直接抛异常(在接口文档中说明异常种类)
通过Optional处理的目的,一是通过返回值类型来提示使用者,返回的对象在业务逻辑上讲是可能为空的,需要注意;二就是它本身支持流式编程,更符合java8的编程习惯
2.入参空值的处理
对于一些方法,我们并不知道它的参数是否可以为空,所以需要一些提示来告诉我们如何传参。
1.通过jsr303规范进行强制约束
就是这种的,通过spring的AOP操作来校验,调用方法的时候就会做强制校验不能为null
2.通过jsr305规范进行弱提示
这种方式主要针对一些祖传代码,不方便整体改造的。这个注解需要引入jar包,因为它不是spring原生的。
需要注意的是,不要在入参中使用Optional,避免造成二义性