应使用assert替代手动throw校验以提升简洁性与可读性,但仅适用于开发/测试阶段;spring的assert.notnull、hastext等方法可一行完成非空、非空字符串等校验。

用断言(Assert)替代手动 throw 校验,能显著减少样板代码,让参数检查更简洁、可读性更高,但需注意适用场景——它适合开发/测试阶段快速失败,不适用于必须向调用方明确抛出业务异常的生产校验。
用 Assert.notNull / hasText 替代 if + throw
Spring 的 org.springframework.util.Assert 提供了大量静态断言方法,一行即可完成非空、非空字符串、范围校验等,无需写冗长的 if 判断:
-
Assert.notNull(id, "id must not be null")→ 替代if (id == null) throw new IllegalArgumentException("id must not be null") -
Assert.hasText(name, "name cannot be blank")→ 自动判 null 和 trim 后为空 Assert.isTrue(age > 0 && age → 替代自定义条件判断
配合 @Valid + Assert 实现分层校验
Controller 层用 @Valid 做 DTO 基础校验(如 @NotBlank),Service 层用 Assert 做业务规则校验(如“用户状态必须为 ACTIVE”),避免把校验逻辑混在业务计算中:
- DTO 中声明字段级约束,由框架自动触发
- Service 方法开头集中用 Assert 检查跨字段或依赖上下文的条件,例如:
Assert.state(user.getStatus() == Status.ACTIVE, "user is not active") - 这样既保持职责清晰,又避免重复 if 块污染核心逻辑
注意断言的启用边界
Java 原生 assert 关键字默认关闭,而 Spring Assert 是普通方法调用,始终生效。但正因如此,要避免误用于需精确异常类型的场景:
- Assert 失败统一抛
IllegalArgumentException或IllegalStateException,不能替换成自定义业务异常(如UserNotFoundException) - 对外 API 或需要被上层 catch 并差异化处理的校验,仍应保留显式 throw
- 高频调用路径中,若校验开销大(如正则匹配、远程查库),不宜塞进 Assert —— 它本质是“快速失败”,不是“通用校验入口”
自定义断言工具类增强语义
可封装带业务语义的静态方法,复用 Assert 同时提升可读性:
-
UserAssert.exists(user)内部调用Assert.notNull(user, "user not found") -
OrderAssert.isPayable(order)封装订单状态 + 金额有效性组合判断 - 这类方法名即文档,比裸写
Assert.isTrue(...)更易懂,也便于统一日志或监控埋点
断言不是万能替代品,而是把“防御性检查”从流程代码里解耦出来的轻量手段。用对地方,代码会干净很多。










