应根据异常是否需调用方强制处理来选择继承exception或runtimeexception:需主动干预的业务异常继承exception,程序缺陷类问题继承runtimeexception。

关键看调用方是否必须处理这个异常,而不是凭感觉或“统一风格”决定。
需要调用方强制响应的场景 —— 继承 Exception
这类异常代表业务中可预期、可恢复、需主动干预的问题。编译器会强制你在调用处加 try-catch 或 throws,避免遗漏关键逻辑。
- 用户余额不足,支付流程必须中断并提示重试或充值
- 订单状态非法(如已取消的订单再次发货),外部系统需明确收到失败信号
- 第三方服务返回特定错误码(如库存扣减失败),上游必须降级或重试
继承 Exception 后,记得提供带业务上下文的构造方法,比如:InsufficientBalanceException(String orderId, BigDecimal balance),方便排查和日志追踪。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
属于程序缺陷或不可恢复问题 —— 继承 RuntimeException
这类异常反映代码逻辑问题或运行时环境异常,不期望调用方兜底,而应由开发阶段发现并修复。
- 参数校验失败(如 ID 为空、金额为负),本质是调用方传参错误
- 配置缺失导致 Bean 初始化失败,属于启动阶段应暴露的问题
- 数据库字段映射为空但业务代码强行调用 getter,属于空指针类逻辑漏洞
继承 RuntimeException 不需要在方法签名声明,也不强制捕获,但建议在全局异常处理器中统一记录堆栈和业务标识,便于定位。
别踩这两个常见坑
一是把所有自定义异常都塞进 RuntimeException —— 看似省事,实则掩盖了本该被显式处理的关键业务分支;二是给每个 HTTP 错误码都建一个 Exception 类 —— 大量细粒度异常反而增加维护成本,优先复用标准异常(如 IllegalArgumentException、IllegalStateException)或按语义分层(如 ValidationException、BusinessException)。
一个实用判断口诀
问自己两个问题:
• 这个错误发生后,调用方不处理就可能出错吗?→ 是 → 用 Exception
• 这个错误发生后,改代码才能解决,不是业务决策能绕过的吗?→ 是 → 用 RuntimeException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










