Java业务异常应继承RuntimeException,主动抛出以表达业务语义;提供多构造方法支持消息、错误码、异常包装;Service层在逻辑校验点提前抛出;统一用@ControllerAdvice处理并返回结构化JSON;区分业务异常(INFO/WARN)与系统异常(ERROR)。

在 Java 业务代码中,抛出自定义业务异常的核心是:定义一个继承自 RuntimeException 的异常类(非检查异常),并在需要的地方用 throw new XxxException(...) 主动抛出。这样既避免强制 try-catch 干扰业务流程,又能清晰表达业务语义。
定义自定义业务异常类
通常建议继承 RuntimeException,不强制上层处理,符合“业务异常非系统故障”的定位。可提供多种构造方法增强可用性:
- 只传消息字符串(便于日志和前端提示)
- 传消息 + 原始异常(用于包装底层异常,保留堆栈)
- 支持错误码(如订单异常、库存异常等不同场景区分)
示例:
public class BusinessException extends RuntimeException {
private final int code;
public BusinessException(String message) {
super(message);
this.code = 400;
}
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
this.code = 400;
}
public int getCode() {
return code;
}
}
在 Service 层按业务规则主动抛出
不要等到 NPE 或 SQL 异常发生才被动响应。应在逻辑判断点提前拦截并抛出,让异常成为业务校验的一部分:
立即学习“Java免费学习笔记(深入)”;
- 参数非法(如手机号格式不对、金额为负)
- 状态不满足(如订单已支付,不能再取消)
- 资源不存在或不可用(如商品已下架、库存不足)
示例:
public void cancelOrder(Long orderId) {
Order order = orderMapper.selectById(orderId);
if (order == null) {
throw new BusinessException(5001, "订单不存在");
}
if (!"created".equals(order.getStatus())) {
throw new BusinessException(5002, "订单状态不允许取消,当前状态:" + order.getStatus());
}
order.setStatus("cancelled");
orderMapper.updateById(order);
}
统一异常处理,避免暴露堆栈给前端
用 @ControllerAdvice + @ExceptionHandler 拦截自定义异常,返回结构化 JSON(如 {code: 5001, msg: "订单不存在", data: null}),不返回原始异常信息:
- 防止敏感信息泄露(如数据库字段名、路径)
- 保持 API 响应格式统一
- 方便前端根据 code 做差异化提示(如跳转、弹窗、静默重试)
示例:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}
}
注意与系统异常、第三方异常的区分
业务异常 ≠ 网络超时、数据库连接失败、JSON 解析错误等系统级问题。后者应记录 ERROR 日志,并可能触发告警;而业务异常通常是预期内的用户操作问题,记 WARN 或 INFO 即可:
- 用户输错密码 → BusinessException(INFO 级,无需告警)
- Redis 连接 refused → RedisConnectionFailureException(ERROR 级,需监控)
- 调第三方接口返回 500 → 包装为 BusinessException 提示用户“服务暂不可用”,同时单独记录原始异常


















