社交媒体

受检异常 vs 运行时异常

受检异常 vs 运行时异常

钩子:编译器的双标现场

上一段代码,编译器直接飘红不让你过:

FileInputStream in = new FileInputStream("no_such_file.txt");
// 编译报错:unhandled exception: java.io.FileNotFoundException

而下面这段,编译器一声不吭,炸了算你自己的:

int[] arr = {1, 2, 3};
System.out.println(arr[5]);    // 编译通过,运行时 ArrayIndexOutOfBoundsException

同样是异常,为什么一个非要你处理,一个懒得管?

核心:异常家族树

先看族谱(收藏这张图):

Throwable(万物之祖)
├── Error                —— JVM 级重大故障(栈溢出等),程序管不了
└── Exception            —— 程序能管的都在这
    ├── RuntimeException(运行时异常)
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   └── ArithmeticException ...
    └── 其他 Exception(受检异常)
        ├── IOException / FileNotFoundException
        └── SQLException ...

规矩一句话:RuntimeException 及其子孙,编译器不检查(非受检);其他 Exception,编译器强制处理(受检)。Error 不是给你处理的,别碰。

28-异常家族树图.png

正题:编译器为什么双标?

想清楚一件事就通了:这两类异常的来源不一样。

受检异常来自"外部世界"——文件可能不存在、网络可能断、数据库可能连不上。这不是代码写错了,是客观世界有变数。编译器逼你提前表态:出事了怎么办?

// 姿势 1:try-catch 当场接住(自己能兜底)
try {
    FileInputStream in = new FileInputStream("config.txt");
    in.close();
} catch (IOException e) {
    System.out.println("配置缺失,用默认配置");
}

// 姿势 2:throws 上交(自己兜不了,谁调用谁处理)
static void readFile(String path) throws IOException {
    FileInputStream in = new FileInputStream(path);   // 不 try,直接上交
    in.close();
}

运行时异常来自"代码的锅"——空指针、下标越界、除零,本质是逻辑漏洞。编译器认为:这种事你该把代码改对,而不是到处 try 把 bug 藏起来。

// 反面教材:用 try 掩盖逻辑漏洞
try {
    System.out.println(arr[5]);
} catch (ArrayIndexOutOfBoundsException e) {
    // 压住不报——bug 还在,只是看不见了
}

// 正解:写代码时就防住(第 12 篇讲过)
if (5 < arr.length) { ... }

决策:该捕获还是抛出?

一个判断就够——这个后果你处理得了吗?

  • 处理得了(给默认值、重试一次、提示用户)→ catch;
  • 处理不了(缺配置、缺文件,程序没法继续)→ throws 上交,让能处理的人接;
  • 运行时异常别 try,改代码才是根治。

顺便说:写 demo 的时候我被编译器逮了一次——in.close() 居然也抛受检 IOException,不处理编译不过。你以后写 IO 代码一定会遇到,先别慌,这是编译器在帮你。(关资源的终极优雅姿势是 try-with-resources,第 30 篇专讲。)

速查表

对比项 受检异常 运行时异常
代表 IOException、SQLException NPE、越界、除零
继承自 Exception(非 RuntimeException) RuntimeException 及其子孙
编译器 强制处理(try 或 throws) 不检查
来源 外部世界的不确定 代码逻辑漏洞
正确姿势 catch 兜底 / throws 上交 改代码防住,别 try 藏 bug

本文示例代码均已本地实测通过,可直接运行。
对应文件:ExceptionDemo.java


橙码酱,分享更有用的技术知识,助你成为更优秀的开发者。