Java中运行时异常继承自RuntimeException且编译通过,编译时异常继承自Exception但非RuntimeException子类且编译报错;前者反映逻辑缺陷,后者应对环境不确定性。

Java中区分运行时异常和编译时异常,核心就看两点:是否继承自 RuntimeException,以及编译器会不会在写代码时就报错。
看继承关系:是不是 RuntimeException 的后代
这是最本质的判断依据:
- 如果一个异常类直接或间接继承自 RuntimeException(比如
NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException),它就是运行时异常; - 如果它继承自 Exception,但没有继承
RuntimeException(比如IOException、SQLException、ClassNotFoundException),它就是编译时异常。
看编译阶段:IDE 或 javac 会不会拦着你
这是最直观的区分方式:
-
编译时异常:你在 IDEA 里写完代码还没运行,编辑器就标红报错,提示“Unhandled exception”,不加
try-catch或throws就无法通过编译; -
运行时异常:代码能顺利编译通过,但一运行就可能崩溃——比如访问
null对象的方法、数组下标越界、除以零,这些错误只在 JVM 执行到那行时才暴露。
看设计意图:该不该强制程序员处理
这反映了 Java 异常机制的设计哲学:
立即学习“Java免费学习笔记(深入)”;
- 编译时异常代表外部可变因素引发的问题,比如文件是否存在、网络是否通畅、数据库连接是否有效。这些不是代码逻辑缺陷,而是程序运行环境带来的不确定性,所以编译器强制你提前考虑并应对;
- 运行时异常大多源于代码逻辑疏漏,比如没判空就调用方法、没校验参数范围就做运算。这类问题本应由开发阶段发现并修复,而不是靠异常处理掩盖,因此编译器不做强制要求。
注意两个常见误区
避免混淆概念:
- 语法错误不是异常:比如少个分号、括号不匹配,属于编译失败(compile error),不属于任何异常体系;
-
Error 不是异常:像
OutOfMemoryError、StackOverflowError是Throwable的子类,但属于系统级严重错误,程序通常无法恢复,也不归入“异常处理”的讨论范畴。










