Java自定义异常基类应继承RuntimeException或Exception,提供三个标准构造器,支持errorCode但避免HTTP层字段,命名用BusinessException并按模块分包。

Java 自定义异常基类的设计,核心是为整个项目建立统一、可扩展、语义清晰的异常体系起点。它不直接对应某个具体业务错误,而是提供通用能力与规范约束,让所有子异常(如 InsufficientBalanceException、OrderNotPayedException)保持行为一致。
继承关系要明确:按场景选 Exception 还是 RuntimeException
基类必须继承 Throwable 的直接子类,不能直接继承 Throwable 本身。主流实践分两类:
-
业务异常基类建议继承
RuntimeException:企业级 Web 项目中绝大多数业务异常(如参数校验失败、状态不合法、权限不足)属于“程序逻辑上不该发生,但运行时可能触发”的情形。用运行时异常避免在 Service 层到处写throws,也防止调用方忽略处理; -
受检异常基类可继承
Exception:仅在极少数强契约场景下使用,比如 SDK 对接外部系统时,要求调用方必须显式处理某种协议错误,此时基类继承Exception并强制try-catch或throws。
构造方法必须覆盖三种标准签名
无论继承哪个父类,基类至少需提供以下三个构造器,确保异常链完整、调试信息不丢失:
-
public BusinessException()—— 空参构造,调用super(); -
public BusinessException(String message)—— 带提示文本,调用super(message); -
public BusinessException(String message, Throwable cause)—— 带原始异常原因,调用super(message, cause)。
不推荐只留一个带参构造,否则在封装底层技术异常(如 SQLException)时会丢失堆栈;也不建议重写 getMessage() 或 getCause(),以免干扰日志系统和监控工具解析。
可扩展但克制:是否加 errorCode、httpStatus 等字段?
基类可以预留通用业务字段,但不宜过度设计:
- 加
private final String errorCode和对应 getter 是常见且推荐的做法,便于统一映射前端提示或国际化; - 避免在基类中加入
HttpStatus、responseBody等 HTTP 层概念 —— 这属于 Controller 层或全局处理器(@ControllerAdvice)的职责,混入基类会污染异常模型的纯粹性; - 如需携带上下文数据(如订单 ID、用户 ID),建议用
Map或轻量级 DTO,而非在每个子类里重复定义字段。
命名与包结构要体现层级意图
基类名称应反映其定位,例如:
-
BusinessException(推荐)—— 清晰表达这是业务语义异常的顶层基类; -
AppException或BaseException容易歧义,可能被误用于包装系统异常; - 放在
com.yourcompany.exception下,子类按模块分包(如order、payment),方便扫描和维护。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











