直接继承 RuntimeException 即可,命名需体现具体业务场景如 InsufficientBalanceException,提供 2–3 个实用构造函数,通过 @ControllerAdvice 统一处理,避免泛化父类以保持类型语义清晰。

直接继承 RuntimeException 即可,无需重写任何方法,重点在于命名清晰、语义明确、便于捕获和处理。
命名体现业务场景
类名应直指业务问题,避免泛泛叫 BusinessException 这类模糊名称。比如:
-
InsufficientBalanceException(余额不足) -
OrderAlreadyPaidException(订单已支付) -
ProductOutOfStockException(商品缺货)
这样在日志、监控或 IDE 跳转时,一眼就能理解异常意图。
构造函数保持简洁实用
提供 2–3 个常用构造方式即可,覆盖大多数使用场景:
- 仅传消息:
public InsufficientBalanceException(String message) - 带原因(用于链路追踪):
public InsufficientBalanceException(String message, Throwable cause) - 可选:带业务码(如返回给前端的错误码):
public InsufficientBalanceException(int code, String message)
不建议塞太多重载,也不需要序列化支持(除非跨 JVM 通信)。
无需 try-catch 包裹,但需统一处理
作为运行时异常,它天然不强制捕获,适合用全局异常处理器统一响应。例如 Spring Boot 中:
- 用
@ControllerAdvice拦截所有自定义业务异常 - 返回标准 JSON 格式(含
code、message、timestamp) - 日志中记录异常全类名 + 消息,方便排查
这样既保持代码干净(不用到处写 try-catch),又保障了错误可观测性。
慎用“包装”或“泛化”父类
不要为了省事定义一个 BaseBusinessException 让所有业务异常去继承——这会削弱类型语义。每个异常应是独立的、不可替代的类型。否则:
- 无法用
instanceof精准识别具体业务问题 - 全局处理器里只能靠字符串匹配判断,脆弱且难维护
- API 文档或 OpenAPI 生成器无法区分不同错误场景
真正的轻量,是职责单一、边界清晰,不是类数量少。










