
在业务逻辑开始前,用 if 判断配合 throw 抛出异常,是最直接、清晰的参数校验方式。关键不是“能不能做”,而是“怎么抛得合理、接得住、不伤业务主流程”。
校验什么?优先检查「不可继续执行」的参数
不是所有参数都要校验,重点拦住会导致后续逻辑崩溃或产生脏数据的输入:
-
必填字段为空:如用户ID、订单号、手机号为
null或空字符串("") -
类型明显错误:期望是正整数却传了负数或小数(如分页参数
pageNo = -1) -
格式硬性约束:邮箱没
@、手机号长度不对、日期字符串无法解析 - 业务唯一性前置依赖:如「创建用户时昵称已存在」——虽需查库,但属于创建前必须确认的准入条件
怎么 throw?用语义明确的异常类型 + 有用的信息
别只写 throw new RuntimeException("错了")。要让调用方或日志能一眼看懂问题在哪:
- 用领域相关的异常类,比如
IllegalArgumentException(参数非法)、IllegalStateException(状态不满足)、或自定义的UserValidationException - 消息里带具体字段名和违规值:
throw new IllegalArgumentException("userId 不能为空"),或更优:"手机号格式错误:实际值='" + phone + "'" - 必要时附上错误码(如
ERROR_PARAM_PHONE_INVALID),方便前端统一映射提示
校验位置:紧贴方法入口,越早越好
把校验逻辑放在方法第一行,不要等查完数据库、建完对象再回头发现参数错了:
public Order createOrder(String orderId, String userId, BigDecimal amount) {
if (StringUtils.isBlank(orderId)) {
throw new IllegalArgumentException("orderId 不能为空");
}
if (StringUtils.isBlank(userId)) {
throw new IllegalArgumentException("userId 不能为空");
}
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("amount 必须为正数");
}
// ✅ 此时参数可信,才进行后续:查用户、锁库存、生成订单...
}
和全局异常处理配合,别让异常穿透到前端页面
单独 throw 只是半步。必须配一个全局异常处理器(如 Spring 的 @ControllerAdvice),把校验异常转成标准响应格式:
- 捕获
IllegalArgumentException,返回 HTTP 400,并附带{"code": 400, "msg": "userId 不能为空"} - 避免把堆栈信息暴露给前端,也防止因未捕获异常导致事务不回滚
- 这样业务方法保持干净,专注核心逻辑,校验和兜底由框架层统一收口

















