核心是解耦校验逻辑与错误处理,提升主流程清晰度、错误语义明确性及扩展性;应定义语义清晰的自定义异常(如UserNotFoundException)、封装校验方法、避免主流程堆砌if判断。

用自定义异常替代大量 if 判断,核心不是“消灭 if”,而是把校验逻辑和错误处理解耦,让主流程更清晰、错误语义更明确、扩展性更强。
定义语义清晰的自定义异常
避免泛泛地 throw new RuntimeException("参数错误"),而是为不同业务场景创建具体异常类,比如:
- UserNotFoundException —— 查不到用户时抛出
- InsufficientBalanceException —— 余额不足时抛出
- InvalidOrderStatusException —— 订单状态非法时抛出
这些异常可继承 RuntimeException(非检查异常),无需强制 try-catch,适合业务校验类错误。
把校验逻辑抽成独立方法,内部抛异常
不要在 service 主方法里堆砌 if (xxx == null) { throw ... },而是封装成校验方法:
立即学习“Java免费学习笔记(深入)”;
private void checkUserExists(Long userId) {
if (userRepository.findById(userId).isEmpty()) {
throw new UserNotFoundException("用户不存在,ID:" + userId);
}
}
private void checkBalanceEnough(Long userId, BigDecimal amount) {
BigDecimal balance = accountService.getBalance(userId);
if (balance.compareTo(amount) < 0) {
throw new InsufficientBalanceException("余额不足,当前:" + balance + ",需:" + amount);
}
}
主流程就变成:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
public void transfer(Long fromId, Long toId, BigDecimal amount) {
checkUserExists(fromId);
checkUserExists(toId);
checkBalanceEnough(fromId, amount);
// ... 执行转账
}
主干干净,校验意图一目了然。
用 AOP 或拦截器统一处理异常
所有自定义异常不必在每个方法里 try-catch。通过 @ControllerAdvice 或 @ExceptionHandler 统一捕获并转换为标准响应格式:
@ExceptionHandler(UserNotFoundException.class)
@ResponseBody
public Result<?> handleUserNotFound(UserNotFoundException e) {
return Result.fail(404, e.getMessage());
}
这样 Controller 层完全不用关心“怎么报错”,只专注“做什么”。前端也收到结构一致的错误码和提示。
配合断言工具(如 AssertJ、Spring Assert)简化写法
Spring 自带的 Assert 工具类能让校验更简洁:
Assert.notNull(userId, "用户 ID 不能为空");
Assert.isTrue(amount.compareTo(BigDecimal.ZERO) > 0, "转账金额必须大于 0");
// 失败时默认抛 IllegalArgumentException,也可包装成自定义异常
if (userRepository.findById(userId).isEmpty()) {
throw new UserNotFoundException(...);
}
适合轻量校验;复杂业务规则仍建议用上文的专用校验方法。

















