Java中受检异常的定义
Java中的异常分为受检异常和非受检异常两大类,受检异常指的是在编译阶段就会被编译器检查的异常类型,所有继承Exception但不继承RuntimeException的异常类都属于受检异常。这类异常通常是程序运行过程中可能出现的、可以被预见并且需要处理的外部错误,比如文件读取失败、网络连接中断、数据库操作出错等场景对应的异常。

受检异常和运行时异常的核心区别
受检异常和运行时异常最明显的差异在于编译阶段的处理要求:受检异常在编写代码时必须显式处理,否则代码无法通过编译;而运行时异常继承自RuntimeException,编译器不会强制要求处理,开发者可以选择处理也可以不处理。
常见的受检异常包括IOException、SQLException、ClassNotFoundException等,这些异常通常对应程序依赖的外部资源出现的问题,不是程序本身的代码逻辑错误。
Java受检异常的两种处理方式
方式一:使用try-catch捕获处理
第一种处理方式是使用try-catch代码块捕获受检异常,然后在catch块中编写对应的处理逻辑,比如打印错误日志、给用户提示信息、尝试重试操作等。
下面是一个读取文件内容的示例,其中FileReader和BufferedReader的构造方法以及readLine方法都会抛出IOException受检异常,我们需要捕获处理:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CheckedExceptionDemo {
public static void main(String[] args) {
BufferedReader reader = null;
try {
// 创建文件读取对象,可能抛出FileNotFoundException(IOException子类)
reader = new BufferedReader(new FileReader("test.txt"));
String line;
// 读取文件内容,可能抛出IOException
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// 捕获受检异常,打印错误信息
System.out.println("文件操作出现异常:" + e.getMessage());
e.printStackTrace();
} finally {
// 关闭资源,避免资源泄漏
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("关闭文件流出现异常:" + e.getMessage());
}
}
}
}
}
方式二:使用throws声明抛出
如果当前方法不希望处理受检异常,可以在方法声明处使用throws关键字声明抛出该异常,将异常的处理责任交给调用当前方法的上层方法。上层方法要么继续声明抛出,要么使用try-catch捕获处理。
以下是声明抛出受检异常的示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CheckedExceptionThrowDemo {
// 方法声明处使用throws抛出IOException受检异常
public static void readFileContent() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
}
public static void main(String[] args) {
try {
// 调用声明抛出受检异常的方法,必须捕获或者继续声明抛出
readFileContent();
} catch (IOException e) {
System.out.println("读取文件失败:" + e.getMessage());
}
}
}
受检异常的使用建议
在实际开发中,不需要对所有的受检异常都进行处理,可以根据场景选择:如果异常出现后当前方法有能力处理,就使用try-catch捕获;如果当前方法没有合适的处理逻辑,就使用throws声明抛出,让更上层的业务模块处理。
需要注意的是,不要盲目捕获受检异常后什么都不做,也不要过度使用throws声明抛出大量异常,否则会让代码的异常处理逻辑变得混乱,也不利于问题的排查。
| 对比项 | 受检异常 | 运行时异常 |
|---|---|---|
| 继承关系 | 继承Exception,不继承RuntimeException | 继承RuntimeException |
| 编译检查 | 必须显式处理,否则编译失败 | 不强制要求处理 |
| 常见场景 | 外部资源操作、依赖组件调用出错 | 代码逻辑错误,如空指针、数组越界 |