java异常传递与多catch捕获协同工作:异常沿调用栈逐层向上抛出,直至被匹配的catch块捕获或程序终止;多catch按从上到下、子类优先顺序匹配,java 7支持互不继承的异常类型用|合并捕获。

Java异常传递和多catch捕获不是两个孤立机制,而是协同工作的核心环节:异常从抛出处逐层向上传递,而多catch块则在某一层决定如何精准拦截和响应不同类型的异常。
异常是怎么一层层“往上走”的
当方法内部抛出异常,JVM会立即停止当前方法剩余代码的执行,并检查该方法是否用try-catch处理了这个异常:
- 如果当前方法有匹配的catch块,异常就被就地处理,流程继续向下(包括finally)
- 如果没有捕获,异常对象自动“甩给”调用它的上层方法——这个过程叫异常传递(propagation)
- 传递会持续向上,直到main方法;若main也没处理,线程终止并打印堆栈跟踪
- 对于受检异常(如IOException),编译器强制要求:要么用try-catch捕获,要么用throws声明交给调用者,否则编译失败
多个catch块怎么选中真正要处理的那个
一个try后面可以跟多个catch,但JVM按书写顺序从上到下依次比对异常类型,一旦匹配就执行对应块,其余catch不再检查:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 必须把子类异常写在父类异常前面,比如先写FileNotFoundException,再写IOException;反过来会导致编译错误(因为前者已被后者覆盖)
- Java 7起支持多类型捕获:catch (SQLException | IOException e),适用于处理逻辑完全相同时
- 每个catch里的异常变量e,可调用getMessage()、printStackTrace()或getCause()获取上下文信息
为什么finally和try-with-resources不能少
无论异常是否发生、是否被捕获,finally块中的代码都保证执行——这是释放资源最可靠的兜底方式:
- 常见用途:关闭文件流、数据库连接、网络Socket等,防止资源泄漏
- 更现代的做法是用try-with-resources(JDK 7+),只要资源实现AutoCloseable接口,就能自动关闭,无需显式写finally
- 注意:如果try和finally里都抛异常,finally中的异常会覆盖try中的,除非你主动保存并重新抛出原始异常
包装异常与自定义异常的实际价值
直接把底层异常(比如SQLException)暴露给业务层,既不安全也不易理解。合理做法是“包装”:
- 在catch里捕获原始异常,再throw一个新的业务异常(如ServiceException),并把原始异常作为cause传入构造函数
- 这样既能隐藏技术细节,又保留完整调用链,便于排查问题
- 自定义异常应继承Exception(受检)或RuntimeException(非受检),根据是否强制调用方处理来选择
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










