必须子类在前,因为catch按顺序匹配,父类异常若在前会捕获所有子类异常,导致后续子类catch块不可达而编译失败。

Java 中多重 catch 的异常顺序必须遵循子类在前、父类在后的原则,否则编译不通过。
为什么必须子类在前?
Java 的 catch 块按从上到下的顺序匹配异常类型。一旦某个 catch 捕获成功,后续的 catch 就不再执行。如果父类异常(如 Exception)写在前面,它会提前“吃掉”所有子类异常(如 NullPointerException、IOException),导致后面的子类 catch 永远无法到达,变成不可达代码(unreachable code)——编译器直接报错。
正确排列示例
以下写法合法且推荐:
try {
// 可能抛出多种异常的代码
} catch (FileNotFoundException e) { // 子类
System.err.println("文件没找到");
} catch (IOException e) { // 父类(FileNotFoundException 的直接父类)
System.err.println("IO 错误");
} catch (Exception e) { // 更宽泛的父类
System.err.println("其他异常");
}
- 每个 catch 都有明确职责:具体异常优先处理,通用异常兜底
- 同级异常(如 IOException 和 SQLException)可任意顺序,因无继承关系
- 若同时捕获 RuntimeException 及其子类(如 IllegalArgumentException),也必须子类在前
常见错误写法
下面这段代码编译失败:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
catch (Exception e) { // ❌ 错误:太宽泛,挡住了所有子类
}
catch (NullPointerException e) { // ✅ 编译报错:这个 catch 永远不会执行
}
编译器提示:"exception NullPointerException has already been caught" 或类似 unreachable catch block。
小技巧:用多异常捕获(Java 7+)简化
如果多个异常类型需要执行相同处理逻辑,可用竖线分隔:
catch (IOException | SQLException e) {
logError(e);
}
注意:这种写法要求这些异常类型之间不能有继承关系(否则编译报错),本质是语法糖,仍需保证类型互斥。

















