上一篇
在Java中,通过try-catch块捕获异常:将可能出错的代码放入try块,在catch中处理具体异常,可多级捕获不同异常,finally块确保资源释放,处理方式包括记录日志、恢复操作或重新抛出异常。
在Java开发中,异常处理是保证程序健壮性和可靠性的核心机制,当代码执行过程中出现错误(如文件不存在、网络中断或空指针访问),Java通过”抛出异常”中断正常流程。捕获并合理处理异常能防止程序崩溃,提升用户体验,以下是系统化的处理方案:
异常处理基础:try-catch-finally 结构
try {
// 可能抛出异常的代码
FileInputStream file = new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
// 捕获特定异常
System.err.println("文件未找到: " + e.getMessage());
} finally {
// 无论是否异常都会执行(资源清理)
System.out.println("资源清理完成");
}
- try 块:包裹可能抛出异常的代码。
- catch 块:捕获指定类型的异常并处理。
- finally 块:必执行步骤,用于关闭文件、数据库连接等资源。
多异常捕获策略
多个 catch 块(精准处理)
try {
int[] arr = new int[5];
arr[10] = 30; // 可能抛出 ArrayIndexOutOfBoundsException
} catch (NullPointerException e) {
System.err.println("空指针错误");
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("数组越界: " + e.getMessage());
}
- 规则:子类异常在前,父类异常在后(如
RuntimeException在最后)。
单 catch 多异常(Java 7+)
try {
// 可能抛出多种异常
} catch (IOException | SQLException e) {
System.err.println("IO或数据库错误: " + e.getClass().getName());
}
- 适用于处理逻辑相同的场景。
finally 与 try-with-resources(自动资源管理)
传统 finally 清理
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try { br.close(); } catch (IOException e) { /* 忽略关闭异常 */ }
}
}
Java 7+ 推荐方案:try-with-resources
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
// 自动调用 br.close()
} catch (IOException e) {
System.err.println("IO错误: " + e.getMessage());
}
- 资源类需实现
AutoCloseable接口。 - 避免手动关闭的冗余代码。
异常处理最佳实践
-
避免空 catch 块

// 错误示范:隐藏问题 try { riskyOperation(); } catch (Exception e) { /* 空块 */ } // 正确做法:记录日志或恢复 catch (Exception e) { logger.error("操作失败", e); } -
选择合适异常类型
- 受检异常(Checked Exceptions):如
IOException,编译器强制处理。 - 非受检异常(Unchecked Exceptions):如
NullPointerException,通常由编程错误引起。
- 受检异常(Checked Exceptions):如
-
自定义异常

public class PaymentFailedException extends Exception { public PaymentFailedException(String message) { super(message); } }- 通过继承
Exception或RuntimeException创建业务相关异常。
- 通过继承
-
异常传播
在方法签名中声明throws,交由上层处理:
public void processFile() throws IOException { // 无需立即处理 }
常见误区与解决方案
| 误区 | 后果 | 改进方案 |
|---|---|---|
捕获 Throwable 或 Error |
掩盖JVM严重错误(如 OutOfMemoryError) |
仅捕获可恢复的异常(Exception 子类) |
过度使用 printStackTrace() |
生产环境无法追踪日志 | 集成日志框架(Log4j/SLF4J) |
| 忽略异常上下文 | 难以定位问题根源 | 保留原始异常:throw new CustomException("描述", e); |
- 核心目标:恢复程序状态、提供友好错误信息、保障资源释放。
- 关键原则:
精准捕获(避免笼统的catch (Exception e))
记录完整堆栈信息
优先使用 try-with-resources
自定义异常增强业务可读性
引用说明参考Oracle官方文档《Java™ Tutorials: Exceptions》及《Effective Java》中异常处理准则,遵循Java语言规范(JLS 11),实践建议基于行业共识,如避免空catch块等源于Clean Code规范。
