Java自定义业务异常类应继承RuntimeException,封装错误码、消息模板及上下文参数,便于统一拦截与前端友好返回;需配合@ControllerAdvice全局处理并规范使用。

Java 中自定义业务异常类的核心是继承 RuntimeException(非检查异常),并封装错误码、提示信息、可选上下文参数,便于统一拦截、日志记录和前端友好返回。
继承 RuntimeException,避免强制 try-catch
业务异常通常属于“预期内但不正常”的情况(如余额不足、用户已存在),不应强迫调用方层层处理。因此推荐继承 RuntimeException:
- 避免污染业务代码,不强制添加
throws声明或try-catch - 与框架(如 Spring)的全局异常处理器天然兼容
- 区分于
Exception及其子类(如IOException),后者表示外部不可控问题,需显式处理
定义标准字段:错误码 + 国际化消息模板
一个规范的业务异常类应至少包含:唯一错误码(String 或 int)、消息模板(支持参数占位)、可选业务上下文数据。例如:
public class BusinessException extends RuntimeException {
private final String code;
private final Object[] args; // 用于填充消息模板的参数,如 {username, orderId}
public BusinessException(String code, String message, Object... args) {
super(String.format(message, args));
this.code = code;
this.args = args;
}
// getter 方法(code 和 args 建议提供,方便后续统一处理)
}
错误码建议采用层级命名,如 "USER.NOT_FOUND"、"ORDER.INSUFFICIENT_STOCK",便于分类和排查;消息模板使用 String.format 或更安全的 MessageFormat,避免运行时格式异常。
立即学习“Java免费学习笔记(深入)”;
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
配合全局异常处理器统一响应格式
在 Spring Boot 中,通过 @ControllerAdvice 拦截自定义异常,输出标准化 JSON:
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), String.format(e.getMessage(), e.getArgs()));
}
}
其中 Result 是你定义的统一响应体(含 code、message、data 字段)。这样所有业务异常都走同一出口,前端无需识别多种错误结构,后端也便于做错误码统计和告警。
使用时直接抛出,语义清晰
在 Service 层按需抛出,不包装、不吞掉、不混用系统异常:
-
不推荐:
throw new RuntimeException("用户名已存在")—— 无错误码、无法定位、难国际化 -
推荐:
throw new BusinessException("USER.DUPLICATE", "用户名 {} 已被注册", username)
必要时可扩展支持嵌套异常(cause 参数)、请求追踪 ID(结合 MDC)、甚至自动记录审计日志,但基础版本保持轻量即可。

















