题目
Java中Checked Exception和Unchecked Exception的区别
信息
- 类型:问答
- 难度:⭐
考点
异常分类,checked exception,unchecked exception,异常处理基础
快速回答
Java异常分为两大类:
- Checked Exception:编译器强制要求处理的异常(如IOException)
- Unchecked Exception:编译器不强制处理的运行时异常(如NullPointerException)
核心区别:
- Checked Exception必须显式捕获或声明抛出
- Unchecked Exception不需要在代码中显式处理
1. 核心区别
Java异常体系继承关系:
Throwable
├── Error (Unchecked) // 如OutOfMemoryError
├── Exception
├── RuntimeException (Unchecked) // 如NullPointerException
└── 其他Exception (Checked) // 如IOException关键差异:
| 特性 | Checked Exception | Unchecked Exception |
|---|---|---|
| 继承关系 | 继承Exception但不继承RuntimeException | 继承RuntimeException或Error |
| 处理要求 | 必须用try-catch捕获或用throws声明 | 不强制处理 |
| 发生时机 | 编译时检查 | 运行时出现 |
| 典型示例 | IOException, SQLException | NullPointerException, ArrayIndexOutOfBoundsException |
2. 代码示例
Checked Exception处理示例:
// 必须处理IOException(Checked Exception)
try {
FileReader file = new FileReader("test.txt");
} catch (IOException e) {
System.out.println("文件读取错误: " + e.getMessage());
}
// 或在方法声明中抛出
public void readFile() throws IOException {
FileReader file = new FileReader("test.txt");
}Unchecked Exception示例:
// 可处理但不强制(通常不推荐捕获RuntimeException)
String text = null;
try {
System.out.println(text.length()); // 抛出NullPointerException
} catch (NullPointerException e) {
System.out.println("空指针异常: " + e.getMessage());
}
// 更常见的做法是预防而非捕获
if (text != null) {
System.out.println(text.length());
}3. 最佳实践
- Checked Exception:用于可预见的、程序应恢复的异常(如文件不存在、网络中断)
- Unchecked Exception:用于程序逻辑错误(如空指针、数组越界),通常通过代码修正而非捕获处理
- 避免捕获
RuntimeException后不做任何处理(空catch块) - 自定义异常时根据场景选择继承
Exception(Checked)或RuntimeException(Unchecked)
4. 常见错误
- 错误1:对Checked Exception未处理导致编译错误
// 编译报错:Unhandled exception type IOException
FileReader file = new FileReader("test.txt"); - 错误2:捕获Exception时吞掉所有异常
try { ... } catch (Exception e) { /* 空块 */ } // 致命错误被隐藏! - 错误3:在finally块中返回导致异常信息丢失
5. 扩展知识
- Error vs Exception:Error表示严重系统错误(如内存溢出),通常程序无法恢复
- 异常链:使用
e.initCause()或带cause参数的构造函数保留原始异常信息 - try-with-resources:Java 7+自动关闭资源的语法,需资源实现
AutoCloseable接口try (FileInputStream fis = new FileInputStream("file.txt")) {
// 自动关闭资源
}