Error 表示 JVM 无法维持运行的系统级崩溃,不可捕获修复;Exception 分 checked(需业务决策处理)和 unchecked(应修复代码缺陷),二者设计意图与处理策略截然不同。

Exception 和 Error 在 Java 异常体系中根本不是“同级选手”,而是设计意图完全不同的两类 Throwable 子类:一个面向可干预的业务场景,另一个面向不可控的系统崩坏临界点。
Throwable 的两个不可混用的分支
Java 要求所有可抛出对象必须继承 Throwable,但它只提供两个直接子类——Exception 和 Error,且二者之间没有继承关系。这不是分类疏忽,而是契约式划分:
-
Error表示 JVM 自身已无法维持基本运行状态(如堆内存彻底耗尽、栈帧爆炸、类加载器链断裂),此时程序逻辑已失去意义 -
Exception表示“程序还活着,只是某条路径走不通了”,比如文件被删、网络断开、参数传错——这些是业务代码能感知、能响应、甚至能兜底的
捕获 Error 不是“防御性编程”,而是掩耳盗铃
你确实可以写 catch (Error e),编译器不拦你,但 JVM 不保证后续行为可靠。常见后果包括:
- 对象状态损坏(例如 OOM 后部分字段未初始化完成,却继续执行 setter)
- 线程局部变量残留脏数据,污染后续请求(尤其在 Tomcat 等复用线程场景)
-
NoClassDefFoundError频繁出现时,catch 住只会掩盖 classloader 隔离或 jar 包版本冲突,改代码毫无作用
真正该做的是监控 + 告警 + 重启,而不是 try-catch。
立即学习“Java免费学习笔记(深入)”;
Exception 分两类,处理策略天差地别
不是所有 Exception 都该 catch,关键看它是 checked 还是 unchecked:
-
IOException、SQLException这类 checked 异常:编译器强制你面对——要么try-catch处理,要么throws推给调用方。因为它们代表外部依赖失败,程序本身没 bug,但需要业务决策(重试?降级?提示用户?) -
NullPointerException、IllegalArgumentException这类 unchecked 异常:编译器不管,但你应该修复——它们暴露的是代码逻辑缺陷,比如忘了判空、参数校验缺失,补 catch 只是把问题藏得更深
最易被忽略的一点:Error 的发生往往意味着 JVM 参数、部署环境或依赖包管理出了问题,而不是应用代码要改;而多数 Exception 的根因在业务路径设计或外部交互契约上,光靠异常处理代码解决不了本质问题。


















