自定义异常滥用会拖垮可维护性,应控制数量(每模块5–8个)、统一继承businessexception基类、区分受检/非受检异常、仅在业务边界抛出并包装底层异常。

自定义异常本身不是问题,滥用才是——比如无节制地新建异常类、不统一继承体系、抛出时不带上下文、捕获后只吞不记日志。防止它拖垮可维护性,关键在设计克制、传播清晰、使用一致。
控制数量,按业务域收敛异常类型
一个模块或服务下,自定义异常不宜超过 5–8 个。过多意味着职责过细、语义重叠。例如用户中心可保留:
• UserAlreadyExistsException
• UserNotFoundException
• InvalidPasswordException
• AccountLockedException
• TooManyLoginAttemptsException
避免再拆出 PasswordTooShortException、PasswordMissingDigitException 等粒度太小的类型。真有校验组合逻辑,用同一个 InvalidPasswordException + 错误码(如 PASS_001 / PASS_002)区分更轻量。
统一基类与构造规范,杜绝空异常
所有业务异常应继承同一基类(如 BusinessException),且必须提供以下构造函数:
• BusinessException(String message)
• BusinessException(String message, Throwable cause)
• BusinessException(String errorCode, String userMessage, Throwable cause)
禁止出现 throw new BusinessException(); 这种无消息、无堆栈、无错误码的“三无异常”。日志里只剩类名,等于没报错。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
明确受检与非受检的分工,不强求处处 try-catch
• 业务异常(如 InsufficientBalanceException)→ 继承 RuntimeException,调用方按需捕获,不强制中断编译流
• 系统异常(如 DatabaseConnectionException)→ 继承 Exception,强制上层声明或处理,体现外部依赖不可靠性
混用会导致:该被关注的异常被忽略,不该强制处理的异常逼人写一堆无效 try-catch,最终大家索性全 catch(Exception e) —— 这是最典型的维护灾难。
只在业务边界抛出,不在工具层或 DAO 层裸抛
异常应在有意义的语义层抛出,而非技术细节层:
• DAO 层捕获 SQLException,包装为 UserPersistenceException(含原始 cause)再向上抛
• Service 层校验失败时,直接抛 InsufficientStockException,而不是先抛 IllegalArgumentException 再层层转译
• Controller 层不抛自定义异常,而是由 @ControllerAdvice 统一转成 HTTP 响应
这样各层职责分明,异常链干净,排查时一眼能定位是业务规则卡住,还是底层连不上库。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










