runtimeexception 是不可修复的逻辑错误,源于代码违背基本契约,如空指针、越界访问等,必须修改代码根治;而 ioexception、sqlexception 等 exception 可预判、有外部诱因,支持重试或降级恢复。

RuntimeException 不是“需要 catch 的错误”,而是程序内部逻辑失当的信号。它代表一种不可修复的运行时状态——不是环境波动或外部依赖失败,而是代码本身违背了基本契约,比如传入 null 却没校验、访问越界数组、用错类型转换。这种问题无法靠重试、降级或兜底来掩盖,必须修改代码逻辑才能根治。
可修复异常:来自外部或可预期的干扰
这类异常属于 Exception(非 RuntimeException),特点是:能预判、有外部诱因、具备恢复条件。
- 文件读取失败(
IOException):磁盘满、权限不足、网络中断——可重试、换路径、返回默认值 - 数据库连接超时(
SQLException):网络抖动或服务暂不可用——可降级为缓存数据或提示重试 - 类加载失败(
ClassNotFoundException):依赖缺失或版本不匹配——可检查 classpath 或动态 fallback
不可修复状态:源于代码逻辑缺陷
RuntimeException 及其子类,本质是程序写错了,不是“发生了意外”,而是“本就不该发生”。它的存在说明前置约束被破坏,系统已处于非法状态。
-
NullPointerException:对象未初始化就调用方法——应提前判空或保证构造完整 -
IllegalArgumentException:参数明显违规(如年龄传 -5)——应在入口处校验并拒绝非法输入 -
ArrayIndexOutOfBoundsException:索引未做边界检查就访问数组——应先验证i >= 0 && i -
IllegalStateException:对象处于不允许执行该操作的状态(如未初始化就调用 start())——需明确状态机规则并守约
怎么判断一个异常该不该 throw RuntimeException?
问三个问题:
- 这个错误能否通过改配置、换网络、重启服务解决?→ 不能 → 属于 RuntimeException
- 是否只要调用方传入合法参数、按正确顺序调用,就绝不会触发?→ 是 → 属于 RuntimeException
- 捕获它之后,除了打日志+告警,还能做什么实质性恢复?→ 基本不能 → 就不该 catch,而该修复源头
实际开发中的处理原则
对 RuntimeException,重点不在“捕获”,而在“预防”和“暴露”:
- 在 API 入口强制校验参数(如用
Objects.requireNonNull()或自定义断言) - 用 IDE 提示 + SpotBugs/PMD 检测空指针、资源泄露等典型模式
- 单元测试覆盖边界条件(null、负数、空集合、越界索引)
- 生产环境保留完整堆栈,配合监控快速定位哪段逻辑崩了











