Assert工具(断言)的使用

博客介绍了Java中Assert机制的使用,通过示例展示了如何利用Assert进行参数检查,以避免空指针异常和非法参数。使用Assert可以简化代码,当参数不符合预期时抛出IllegalArgumentException。结合全局异常处理类,可以优雅地处理这类异常,返回友好的错误信息。此外,对比了没有使用断言时的冗余代码,突显了断言在提高代码可读性和维护性上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

assert机制

其实就是相当于判断工具,如果不符合期待,就抛出异常,异常信息为自定义的message。
代码:

原生assert(java关键字assert)例子:
assert !StringUtils.isEmpty(request.getName());

assert工具类列子(如spring的Assert)Assert.hasText(null,"参数错误");
Assert.notNull(null,"asdf");
Assert.isTrue(false,"判断错误");

为什么要用assert

最直接的原因就是为了简化代码。

可以看下下面代码的区别。
不用断言:

String username="";
String password="";
if(StringUtils.isNotEmpty(username)){
    return "用户名不能为空";
}
if(StringUtils.isNotEmpty(username)){
    return "用户名不能为空";
}

使用断言:

try {
    String username="";
    String password="";
    Assert.hasLength(username,"用户名不能为空");
    Assert.hasLength(username,"密码不能为空");
}catch (IllegalArgumentException e) {
    logger.error("errorMessage:{}", e.getMessage(), e);
}

断言配合全局异常处理来用很不错:

@ControllerAdvice("com.test")
@ResponseBody
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public String illegalArgumentExceptionHandler( IllegalArgumentException ex) {
        return ex.getMessage();
    }
}

完整版代码(包括异常处理)

代码:

JsonResult result = new JsonResult<>();
String methodName="定制断言功能_断言工具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));
    return result;
}catch(IllegalArgumentException e){ // 注:这里虽然是异常,但是打失败的日志,和不期待的异常区分开
	log.info(methodName+"请求失败,{}",e.getMessage()); // 这里的写法注意下,去掉error=,直接用{}
    return JsonResult.error("-1",methodName+"请求失败,"+e.getMessage());
}catch(Exception e){
    log.error(methodName+"请求异常,error=",e);
    return JsonResult.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类。

对比下就比较清楚了:

assertAssertUtils
是否受环境限制受环境限制,默认是关闭不受环境限制
报错异常类型为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也是可以的。

自定义断言工具代码

也是网上通用的代码:

/*
 * 定制断言工具
 */
public class CustomAssertUtils {
    public static void isNotEmpty(String string,String message){
        if(!StringUtils.isNotEmpty(string)){
            throw new IllegalArgumentException(message);
        }
    }

    public static void isSuccess(boolean b,String message){
        if(!b){
            throw new IllegalArgumentException(message);
        }
    }


    public static void collectionIsNotEmpty(Collection collection, String message){
        if(CollectionUtils.isEmpty(collection)){
            throw new IllegalArgumentException(message);
        }
    }

    public static void collectionIsEmpty(Collection collection, String message){
        if(!CollectionUtils.isEmpty(collection)){
            throw new IllegalArgumentException(message);
        }
    }

    public static void objectIsNotNull(Object object, String message){
        if(ObjectUtils.isEmpty(object)){
            throw new IllegalArgumentException(message);
        }
    }

    public static void objectIsNull(Object object, String message){
        if(!ObjectUtils.isEmpty(object)){
            throw new IllegalArgumentException(message);
        }
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值