Java多异常捕获要求并列异常类型用“|”分隔,禁止父子类混用(如Exception | RuntimeException),因编译器需静态确定匹配分支;异常变量为各类型最小公共父类,不可直接调用子类特有方法。

Java中捕获多个异常,推荐使用多异常捕获(multi-catch)语法,即一个catch块处理多种异常类型,前提是这些异常互不继承、且都属于同一try块可能抛出的检查或非检查异常。
多异常捕获的基本写法
用竖线(|)分隔多个异常类名,异常类型必须是并列关系(不能是父子类),JVM会按顺序匹配第一个能捕获该异常的catch块:
- 语法格式:catch (IOException | SQLException e)
- 异常变量e是final的,不可重新赋值
- 不能写成catch (Exception | RuntimeException e),因为后者是前者的子类,编译报错
为什么不能混用父子异常
多异常捕获要求各类型之间“互斥可替代”,即编译器需能静态确定哪个异常被抛出时该走哪个分支。若允许Exception | NullPointerException,由于后者是前者子类,语义冗余且破坏类型安全:
- 编译器会提示:“Alternatives in a multi-catch statement cannot be related by subclassing”
- 正确做法是只保留父类catch (Exception e),或分别写两个独立catch块
与传统多个catch块的对比
多异常捕获本质是语法糖,等价于多个catch块执行相同逻辑,但更简洁、避免重复代码:
立即学习“Java免费学习笔记(深入)”;
- 传统写法需重复处理逻辑:catch (IOException e) { log(e); throw new ServiceException(e); } 和同样逻辑的SQLException分支
- 多异常写法只需一次:catch (IOException | SQLException e) { log(e); throw new ServiceException(e); }
- 若不同异常需要不同处理,则仍应拆分为独立catch块,不要强行合并
注意事项和常见误区
多异常捕获虽简洁,但有几处容易踩坑:
- 异常变量类型是所有列出类型的**最小公共父类型**(通常是Throwable或Exception),不能调用子类特有方法,如e.getSQLState()在IOException | SQLException中不可用
- 如果需要子类专属操作,应在catch内用instanceof判断后再强转
- Java 7引入该特性,确保项目源码级别≥7(-source 7或更高)










