文章目录
- assert机制
- 为什么要用assert
- 完整版代码(包括异常处理)
- 判断是否是空字符串
- 生产环境为什么不推荐用断言
- assert和AssertUtils的区别
- Assert工具为什么不受断言开关的影响呢?
- spring Assert的使用
- 判断字符串是否为空
- spring只有Assert这一个实现类吗?
- 自定义断言工具
- 自定义断言工具代码
- ReturnAssert工具
assert机制
其实就是相当于判断工具,如果不符合期待,就抛出异常,异常信息为自定义的message。
代码:
原生assert(java关键字assert)例子:assert!StringUtils.isEmpty(request.getName());assert工具类列子(如spring的Assert类):Assert.hasText(null,"参数错误");Assert.notNull(null,"asdf");Assert.isTrue(false,"判断错误");为什么要用assert
最直接的原因就是为了简化代码。
可以看下下面代码的区别。
不用断言:
Stringusername="";Stringpassword="";if(StringUtils.isNotEmpty(username)){return"用户名不能为空";}if(StringUtils.isNotEmpty(username)){return"用户名不能为空";}使用断言:
try{Stringusername="";Stringpassword="";Assert.hasLength(username,"用户名不能为空");Assert.hasLength(username,"密码不能为空");}catch(IllegalArgumentExceptione){logger.error("errorMessage:{}",e.getMessage(),e);}断言配合全局异常处理来用很不错:
@ControllerAdvice("com.test")@ResponseBodypublicclassGlobalExceptionHandler{@ExceptionHandler(IllegalArgumentException.class)publicStringillegalArgumentExceptionHandler(IllegalArgumentExceptionex){returnex.getMessage();}}完整版代码(包括异常处理)
代码:
JsonResultresult=newJsonResult<>();StringmethodName="定制断言功能_断言工具isEmpty";try{log.info(methodName+"请求开始,request={}",JSON.toJSONString(request));Assert.hasLength(request.getName(),"名称不能为空");Assert.hasLength(request.getPassword(),"密码不能为空");Assert.hasLength(request.getAge(),"年龄不能为空");log.info(methodName+"请求完成,result={}",JSON.toJSONString(result));returnresult;}catch(IllegalArgumentExceptione){// 注:这里虽然是异常,但是打失败的日志,和不期待的异常区分开log.info(methodName+"请求失败,{}",e.getMessage());// 这里的写法注意下,去掉error=,直接用{}returnJsonResult.error("-1",methodName+"请求失败,"+e.getMessage());}catch(Exceptione){log.error(methodName+"请求异常,error=",e);returnJsonResult.error("-1",methodName+"请求异常,error="+e.getMessage());}效果一目了然,不用每个判断都单独写log和返回了,集中捕获IllegalArgumentException进行处理即可,当然,如果全局异常处理那更加方便。
判断是否是空字符串
Assert.hasLength("","用户名不能为空");相当于StringUtils.isNotEmpty("");生产环境为什么不推荐用断言
因为断言默认是关闭的,如果没有手动开启,那么相当于无效,容易造成不同环境逻辑不一致,留坑。
编译和运行的时候要加参数,否则编译不通过,或者运行无效。
javac -source 1.4 AssertTest.java # 编译的时候要加 -source 1.4
java -ea AssertTest # 运行的时候要加 -ea
在vm中加-ea(enable assert)表示启用断言。
在vm中加-da(disable assert)表示禁用断言(实际默认就是禁用)。
assert和AssertUtils的区别
注:这里的assert指的是java关键字assert。
AssertUtils指的是封装后Assert工具,如spring的Assert类。
对比下就比较清楚了:
| — | assert | AssertUtils |
|---|---|---|
| 是否受环境限制 | 受环境限制,默认是关闭 | 不受环境限制 |
| 报错 | 异常类型为java.lang.AssertionError,Exception捕获不到(这也挺坑的,因为一般try catch都是用Exception) | 异常类型为java.lang.IllegalArgumentException,Exception可以捕获到 |
这就一目了然了,assert不好用,推荐用Assert工具。
Assert工具为什么不受断言开关的影响呢?
看下实现代码就明白了,Assert工具是用代码模拟出了assert的效果,并没有用到assert关键字,所以不受assert开关的影响。
spring Assert的使用
AssertUtils有很多组织都实现了,如:spring、apache、hutools等。
简单看了下,spring的用着就可以,又不用引入额外包,所以就以spring的Assert类为例。
判断字符串是否为空
用hasLength() 注:不是notEmpty(),因为notEmpty方法是给数组用的。
spring只有Assert这一个实现类吗?
自定义断言工具
有时第三方提供的断言工具功能不满足我们的要求怎么办?
其实可以大胆一点,跳出第三方的限制,直接自定义工具。
因为实现原理很清晰,就是校验不通过,抛出IllegalArgumentException即可。
想通这一点,思路一下子宽了很多。
另外:如果不想把异常分的太细,直接捕获Exception也是可以的。
自定义断言工具代码
也是网上通用的代码:
/* * 定制断言工具 */publicclassCustomAssertUtils{publicstaticvoidisNotEmpty(Stringstring,Stringmessage){if(!StringUtils.isNotEmpty(string)){thrownewIllegalArgumentException(message);}}publicstaticvoidisSuccess(booleanb,Stringmessage){if(!b){thrownewIllegalArgumentException(message);}}publicstaticvoidcollectionIsNotEmpty(Collectioncollection,Stringmessage){if(CollectionUtils.isEmpty(collection)){thrownewIllegalArgumentException(message);}}publicstaticvoidcollectionIsEmpty(Collectioncollection,Stringmessage){if(!CollectionUtils.isEmpty(collection)){thrownewIllegalArgumentException(message);}}publicstaticvoidobjectIsNotNull(Objectobject,Stringmessage){if(ObjectUtils.isEmpty(object)){thrownewIllegalArgumentException(message);}}publicstaticvoidobjectIsNull(Objectobject,Stringmessage){if(!ObjectUtils.isEmpty(object)){thrownewIllegalArgumentException(message);}}}ReturnAssert工具
有时需要return 写if太难看了
booleanb=ReturnAssert.collectionIsEmpty(newArrayList(),message:"");if(!b)returnresult;booleanb=ReturnAssert.collectionIsEmpty(newArrayList(),message:"");if(!b)returnresult;