Java自定义异常应控制在1层抽象,统一继承BusinessException,按语义横向定义子类;构造器需全参数并实现Serializable;受检/非受检选择须匹配调用契约。

Java 自定义异常要避免继承树过深,核心是控制在“1层抽象 + 少量语义子类”以内,不搞多级嵌套继承。深继承链不仅增加理解成本、破坏开闭原则,还容易导致异常捕获模糊、日志上下文丢失、序列化兼容性问题。
顶层只设一个 BusinessException
所有业务异常统一继承自一个 BusinessException(非 RuntimeException 的受检异常,或 RuntimeException 的非受检异常,按团队规范选其一)。它封装通用字段:errorCode、message、cause 和 context(Map 类型,存订单号、用户ID等关键现场信息)。不设 BaseBusinessException → ServiceException → OrderServiceException 这类三级结构。
子类按失败语义横向展开,不纵向分层
真正需要定义子类时,只针对**不可恢复的、有明确业务含义的失败场景**,每个子类表达一种独立语义,且直接继承顶层 BusinessException:
-
OrderNotFoundException—— 订单查无结果,前端可提示“订单不存在” -
InsufficientBalanceException—— 余额不足,触发充值引导 -
PaymentTimeoutException—— 支付超时,允许重试
拒绝 MyException、BaseException、ValidationException(太泛)或 OrderCreateFailedExceptionV2(版本化命名)这类命名。同一个错误码变动,优先改 errorCode 字段值,而不是新增异常类。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
构造器必须全参数,禁止丢失上下文
每个自定义异常类至少提供两个构造器:
BusinessException(String errorCode, String message)BusinessException(String errorCode, String message, Throwable cause)
严禁只留 BusinessException(String message) 单参构造器——这会让调用方无法传入 errorCode,前端无法做差异化提示,日志里也查不到错误分类依据。所有异常类必须实现 Serializable,否则在 Dubbo、RocketMQ 等跨进程场景中会反序列化失败。
受检与非受检的选择要服务于调用契约
如果异常代表调用方**必须决策如何恢复**(如库存不足需降级),用受检异常(继承 Exception);如果代表**程序逻辑缺陷或外部不可控故障**(如网络超时、数据库连接失败),用非受检异常(继承 RuntimeException)。不要为“统一风格”强行把所有异常都做成受检或非受检——混淆语义比层级深更危险。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










