error是jvm或系统级不可恢复错误,如outofmemoryerror;exception是程序可控的可处理异常,分受检(如ioexception)和非受检(如nullpointerexception)两类。

Java 的异常体系里,Error 和 Exception 都继承自 Throwable,但它们代表完全不同的问题层级——一个指向系统崩溃,一个指向程序可控的意外。
语义定位与设计意图不同
这二者最根本的区别在于“谁该负责”和“能不能救”:
-
Error 是 JVM 自身或底层运行环境出的问题,比如内存耗尽(
OutOfMemoryError)、栈溢出(StackOverflowError)、类加载失败(NoClassDefFoundError)。它不是你代码写错了,而是整个执行基础塌了。 -
Exception 是程序在正常流程中可能遇到、也理应能应对的意外,比如文件找不到(
FileNotFoundException)、空指针(NullPointerException)、数组越界(ArrayIndexOutOfBoundsException)。它属于业务逻辑的一部分,设计上就预留了处理路径。
是否需要捕获?编译器怎么看
Java 编译器对这两类的态度截然不同:
-
Error 及其子类不强制捕获,也不建议捕获。即使写了
catch (Error e),通常也只是记录日志后退出,因为 JVM 很可能已无法保证后续行为可靠。 -
Exception 分两类:
-
受检异常(Checked Exception):如
IOException、SQLException。编译器强制你处理——要么try-catch,要么用throws声明抛出。这是提醒你:外部依赖不稳定,得有兜底。 -
非受检异常(Unchecked Exception):即
RuntimeException及其子类,如NullPointerException。编译器不管,但你应该通过代码健壮性(比如判空、校验索引)来预防,而不是靠 catch 挡着。
-
受检异常(Checked Exception):如
恢复能力与处理策略差异
能不能恢复,决定了你怎么写代码:
- 遇到 Error,基本没得救。比如
OutOfMemoryError发生时,JVM 已经没有足够堆空间继续运行;StackOverflowError意味着调用链失控,再 catch 也解决不了递归逻辑缺陷。这类情况,监控报警比 try-catch 更实际。 - 遇到 Exception,多数可以恢复。例如读取配置文件失败,可切换默认配置;数据库连接超时,可重试或降级返回缓存数据。这种“分支逻辑”正是异常机制存在的意义。
自定义异常该继承谁
如果你要写自己的异常类型,记住这个铁律:
- 想让调用方必须处理(比如支付失败必须记录并通知用户),就继承
Exception,做成受检异常。 - 想表达程序逻辑错误(比如参数非法、状态不匹配),就继承
RuntimeException,让它自然抛出,不干扰调用链。 - 永远不要继承 Error。自定义错误不属于你的应用职责范围,强行模仿只会混淆问题边界。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











