应构建分层的自定义异常基类:businessexception(继承exception)处理可预期业务异常,systemexception(继承runtimeexception)处理不可恢复系统异常,并统一支持错误码、上下文信息及原因链传递,适配全局异常处理器。

构建可复用的企业级自定义异常基类,核心在于合理利用Java继承机制,统一异常语义、标准化构造行为,并为不同业务场景提供灵活扩展能力。不建议每个异常都单独写一个孤立类,而应先设计一个健壮的基类,再按需派生具体异常。
定义统一的异常基类
企业级应用通常需要区分“可预期的业务异常”和“不可恢复的系统异常”,因此推荐设计两个顶层基类:一个继承 Exception(用于受检异常,如参数校验失败、状态冲突),另一个继承 RuntimeException(用于非受检异常,如非法操作、断言失败)。两者都应包含以下关键要素:
- 标准构造函数:支持仅传 message、message + cause、以及带业务错误码(如 errorCode: String)的重载
- 内置错误码字段(String 或枚举),便于日志归类、前端映射、监控告警
- 可选的上下文信息字段(如 requestId、userId),方便问题追踪
- 重写
toString()或提供toLogString()方法,确保日志输出结构清晰
按职责分层继承,避免“一锅炖”
不要让所有业务异常都直接继承 Exception 或 RuntimeException。应在基类之上建立中间层,体现领域语义:
- BusinessException(继承 Exception):封装需显式处理的业务规则异常,如订单创建失败、库存不足
- SystemException(继承 RuntimeException):封装技术链路异常,如远程调用超时、数据库连接中断
-
ValidationException(继承 BusinessException):专用于参数/数据校验失败,可携带字段级错误信息(Map
fieldErrors) - AuthException(继承 SystemException):聚焦认证鉴权失败,如 token 过期、权限不足
这种分层使异常类型具备明确语义,调用方能根据父类类型做通用处理(如统一记录审计日志、统一返回 HTTP 状态码),同时保留子类定制能力。
确保堆栈与原因链完整传递
自定义异常若包装底层异常(如将 SQLException 封装为 DataAccessException),必须通过 super(message, cause) 或 initCause(cause) 保留原始异常。否则调试时会丢失关键堆栈信息。常见错误是只传 message,忽略 cause:
- ✅ 正确:
super("订单状态非法", originalException) - ❌ 错误:
super("订单状态非法")(丢失原始异常堆栈) - 建议在基类中提供带 cause 的构造函数模板,并强制子类调用
配合全局异常处理器统一响应
基类设计要适配 Spring 等框架的统一异常处理机制。例如,在 Spring Boot 中:
- 为基类添加标记接口(如
interface BusinessFailure)或注解(如@ResponseStatus),便于 @ControllerAdvice 精准捕获 - 基类提供
getHttpStatus()方法,让不同子类返回对应 HTTP 状态码(如 ValidationException → 400,AuthException → 401) - 避免在基类中硬编码 JSON 序列化逻辑,而是由统一处理器负责格式化输出(含 errorCode、message、timestamp 等标准字段)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











