java捕获多个异常分多重catch块和multi-catch:需不同处理逻辑时用多个catch块,子类异常必须在父类前;需相同处理逻辑时用|分隔的multi-catch,异常类型须无继承关系。

Java 中捕获多个不同类型的异常,主要通过 多重 catch 块 或 多异常捕获(multi-catch)语法 实现,两者适用场景不同,关键在于异常类型是否具有继承关系、是否需要分别处理。
用多个独立的 catch 块分别处理
当不同异常需要执行**不同的恢复逻辑**(比如日志格式不同、重试策略不同、返回值不同),推荐用多个 catch 块,从子类异常写到父类异常(顺序不能颠倒):
- 子类异常必须放在父类异常前面,否则编译报错(如 IOException 不能写在 Exception 后面)
- 每个 catch 块可独立访问对应异常对象,便于针对性处理
示例:
try {
readFile();
connectToServer();
} catch (FileNotFoundException e) {
System.err.println("文件没找到:" + e.getMessage());
// 可能触发本地默认配置加载
} catch (SocketTimeoutException e) {
System.err.println("网络超时:" + e.getMessage());
// 可能重试或降级
} catch (IOException e) {
System.err.println("其他 IO 错误:" + e.getMessage());
// 统一兜底处理
}
用一个 catch 块同时捕获多种异常(multi-catch)
当多个异常类型需要执行**完全相同的处理逻辑**(比如都记录日志后统一抛出自定义异常),可用 | 分隔多个异常类型:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 所有异常类型必须是并列关系(不能有父子继承关系),否则编译失败
- catch 参数是隐式 final 的,不能重新赋值;但可以调用其方法(如 e.getMessage())
- 更简洁,避免重复代码
示例:
try {
doSomething();
} catch (SQLException | IOException | IllegalArgumentException e) {
logger.error("操作失败", e);
throw new ServiceException("业务执行异常", e);
}
注意异常的继承关系和捕获顺序
Java 异常体系中,子类异常更具体,父类异常更宽泛。捕获时必须遵守“先具体、后宽泛”原则:
- 错误写法:catch (Exception e) 写在 catch (NullPointerException e) 前 → 编译不通过
- 正确顺序:NullPointerException → IllegalArgumentException → Exception
- 运行时异常(RuntimeException 子类)和检查异常(Exception 子类但非 RuntimeException)可共存于同一 try 块中
配合 try-with-resources 自动管理资源时的异常处理
使用 try-with-resources 时,如果 try 块和资源关闭过程都抛出异常,try 块的异常会被抛出,关闭异常被抑制(suppressed),可通过 e.getSuppressed() 获取:
- 仍可用多重 catch 处理主异常
- 若需关注关闭异常,应在 catch 中显式检查 getSuppressed()
示例:
try (FileInputStream fis = new FileInputStream("a.txt")) {
process(fis);
} catch (IOException | SQLException e) {
System.err.println("主异常:" + e);
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("被抑制的异常:" + suppressed);
}
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










