1. 概述

本文将深入探讨 Spring 框架中的 Assert 工具类,解析其核心设计理念,并通过实际代码演示如何高效使用它进行参数校验。这个工具类虽然简单,但在 Spring 生态中无处不在,掌握它能帮你写出更健壮的代码。

2. Assert 类的核心价值

Spring Assert 类本质是一个参数校验工具集,它的核心价值在于:

提供简洁的断言方法:用一行代码替代繁琐的 if-throw 模式
明确的异常类型:统一抛出 IllegalArgumentExceptionIllegalStateException
方法签名统一:所有方法都遵循 (condition, message)(condition, messageSupplier) 模式
⚠️ 注意:与 JUnit 断言不同,Spring Assert 专为生产环境参数校验设计,而非单元测试

典型方法特征:

  • 全部静态方法,直接通过 Assert.methodName() 调用
  • 首参数通常是待校验的条件或对象
  • 末参数是异常消息(支持 StringSupplier<String>
  • 校验失败时立即抛出运行时异常

3. 实战示例

以汽车类为例,看看 Assert 如何简化参数校验:

public class Car {
    private String state = "stop";

    public void drive(int speed) {
        Assert.isTrue(speed > 0, "speed must be positive");
        this.state = "drive";
        // ...
    }
}

这行代码等价于:

if (!(speed > 0)) {
    throw new IllegalArgumentException("speed must be positive");
}

当传入负速度时,会直接抛出:

Exception in thread "main" java.lang.IllegalArgumentException: speed must be positive

4. 逻辑断言方法

4.1. isTrue()

最基础的逻辑断言,当条件为 false 时抛出 IllegalArgumentException

Assert.isTrue(condition, "error message");

4.2. state()

isTrue() 签名相同,但抛出 IllegalStateException

Assert.state(this.state.equals("stop"), "car must be stopped");

💡 使用场景:当对象状态不合法时(比如汽车行驶中不能加油)

5. 对象与类型断言

5.1. notNull()

校验对象非空:

public void сhangeOil(String oil) {
    Assert.notNull(oil, "oil mustn't be null");
    // ...
}

5.2. isNull()

校验对象必须为空:

public void replaceBattery(CarBattery carBattery) {
    Assert.isNull(
      carBattery.getCharge(), 
      "to replace battery the charge must be null");
    // ...
}

5.3. isInstanceOf()

校验对象类型:

public void сhangeEngine(Engine engine) {
    Assert.isInstanceOf(ToyotaEngine.class, engine);
    // ...
}

5.4. isAssignable()

校验类型兼容性(is-a 关系):

public void repairEngine(Engine engine) {
    Assert.isAssignable(Engine.class, ToyotaEngine.class);
    // ...
}

6. 文本断言方法

6.1. hasLength()

校验字符串非空(允许纯空格):

public void startWithHasLength(String key) {
    Assert.hasLength(key, "key must not be null and must not the empty");
    // ...
}

6.2. hasText()

更严格的文本校验(至少包含一个非空格字符):

public void startWithHasText(String key) {
    Assert.hasText(
      key, 
      "key must not be null and must contain at least one non-whitespace character");
    // ...
}

6.3. doesNotContain()

校验字符串不包含特定子串:

public void startWithNotContain(String key) {
    Assert.doesNotContain(key, "123", "key mustn't contain 123");
    // ...
}

7. 集合与 Map 断言

7.1. 集合非空校验

public void repair(Collection<String> repairParts) {
    Assert.notEmpty(
      repairParts, 
      "collection of repairParts mustn't be empty");
    // ...
}

7.2. Map 非空校验

public void repair(Map<String, String> repairParts) {
    Assert.notEmpty(
      repairParts, 
      "map of repairParts mustn't be empty");
    // ...
}

8. 数组断言方法

8.1. 数组非空校验

public void repair(String[] repairParts) {
    Assert.notEmpty(
      repairParts, 
      "array of repairParts mustn't be empty");
    // ...
}

8.2. 数组无 null 元素

public void repairWithNoNull(String[] repairParts) {
    Assert.noNullElements(
      repairParts, 
      "array of repairParts mustn't contain null elements");
    // ...
}

⚠️ 注意:空数组(new String[0])会通过此校验

9. 总结

Spring Assert 类虽然简单,但却是 Spring 框架的基石之一。合理使用它能:

  1. 提升代码可读性:用声明式替代命令式校验
  2. 统一异常处理:标准化参数校验异常
  3. 减少样板代码:一行代码替代多行 if-throw

建议在以下场景优先使用:

  • 公共 API 的参数校验
  • 构造函数/工厂方法的参数校验
  • 需要明确表达前置条件的方法

完整示例代码可在 GitHub 项目 中查看,仓库地址:git@github.com:spring-tutorials/assert-examples.git


原始标题:Spring Assert Statements