优先继承exception适用于业务可预期且调用方需立即响应的错误,如支付失败、库存扣减失败;优先继承runtimeexception适用于程序逻辑缺陷等本不该发生的错误,如参数为null、状态不一致。

关键看调用方是否必须显式处理这个错误,而不是错误“严不严重”。
优先继承 Exception 的情况
适用于业务上可预期、调用方有能力且有责任立刻响应的错误。这类异常编译器强制要求处理,避免被忽略。
- 支付失败(余额不足、渠道拒绝)——上层可能要提示用户、引导充值或切换方式
- 库存扣减失败(超卖、锁定失败)——需回滚操作、返回明确提示
- 权限校验不通过(无操作资格)——应拦截请求并返回 403
- 第三方服务不可用(如短信发送限流)——可降级、重试或记录告警
优先继承 RuntimeException 的情况
适用于程序逻辑缺陷、参数非法或状态不一致等本不该发生的错误。这类异常不强制捕获,便于快速暴露问题。
- 方法入参为 null 且契约明确不允许(如 IllegalArgumentException)
- 订单已发货却调用发货接口(IllegalStateException)
- 配置项缺失或格式错误导致启动失败(如 InvalidConfigException)
- 数据库主键冲突但代码未做唯一性检查
容易踩坑的边界场景
有些错误看似“运行时发生”,但其实调用方有合理应对路径,强行用 RuntimeException 反而削弱系统健壮性。
- HTTP 调用返回 503:应封装为 ServiceUnavailableException extends Exception,方便上层触发熔断或重试
- SQL 异常(如唯一键冲突):若属于业务可识别的失败(如注册用户名重复),建议自定义 DuplicateUserException extends Exception
- 文件读取失败(FileNotFoundException):它是 Exception 子类,因为上层可能要提供默认配置或提示用户检查路径
命名与构造建议
无论继承哪个父类,异常名要体现业务语义,不要笼统叫 “BusinessException”。构造函数至少支持 message 和 cause 两个参数。
- 推荐写法:public class InsufficientBalanceException extends Exception { ... }
- 避免空 catch:catch (Exception e) { /* 不做任何事 */ } 会掩盖关键问题
- RuntimeException 子类一般不加 throws 声明,除非是公开 API 的明确契约
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











