Java 异常处理一览 | 基础篇

Java 异常处理一览 | 基础篇

💡 原文中文,约5600字,阅读约需14分钟。
📝

内容提要

本文介绍Java异常处理基础:异常是程序执行中中断正常流程的事件,发生时创建异常对象并抛出,运行时系统沿调用堆栈按相反顺序寻找匹配的异常处理程序(捕获异常),找不到则程序终止。Java异常体系以Throwable为根,分Error和Exception,Exception又分运行时异常和检查型异常。捕获用try-catch,可多catch或一个catch处理多种异常;finally总在try退出时执行,用于释放资源。检查型异常必须捕获或用throws声明抛出。

🔎

延伸解读

异常处理机制:从抛出到捕获的流程

当方法内发生错误时,会创建包含错误类型和程序状态的异常对象,并交给运行时系统,这一过程称为抛出异常。运行时系统沿调用堆栈按方法调用的相反顺序寻找匹配的异常处理程序,找到则捕获并处理;若找遍整个堆栈仍无合适处理程序,程序将终止。理解这一流程有助于在异常发生时快速定位问题,例如通过堆栈信息中第一行确定异常源头。

检查型与非检查型异常:处理策略差异

Java异常体系以Throwable为根,分为Error和Exception。Error表示严重错误,程序通常无法处理;Exception分为运行时异常和检查型异常。运行时异常由代码逻辑错误引起,如空指针、数组越界,应修复代码;检查型异常是程序逻辑的一部分,如IO异常,必须捕获或用throws声明,否则编译失败。非检查型异常不强制处理,但若不处理会沿调用堆栈向上抛,直至被捕获或程序终止。

finally块:确保资源释放与逻辑执行

finally块总是在try退出时执行,无论是否发生异常、是否被捕获,甚至try或catch中有return语句。它常用于释放文件、连接等资源,或执行必须完成的逻辑,如输出摘要日志。若未使用finally,程序中途抛异常可能导致资源泄漏。但需注意,finally中应避免抛出异常或使用return,以免覆盖原有异常或返回值,影响程序正确性。

throws声明:将异常处理责任转移给调用者

当方法内抛出检查型异常但当前方法不适合处理时,可在方法声明中用throws指定可能抛出的异常,将处理责任交给调用堆栈上层。多个异常用逗号分隔。调用者必须捕获或继续声明抛出。对于非检查型异常,throws声明是可选的,不声明时异常会自动向上传播。合理使用throws能保持方法职责单一,但过度使用可能导致异常处理分散,增加调试难度。

❓

Q&A

Java中的异常是什么?

异常是程序执行过程中发生的事件,会中断程序的正常运行。当方法发生错误时,会创建异常对象并交给运行时系统,这一过程称为抛出异常。

Java的异常继承体系是怎样的?

Throwable是异常体系的根,继承自Object。Throwable分为Error和Exception。Error表示严重错误,程序一般无法处理;Exception表示运行时错误,可被捕获处理。Exception又分为RuntimeException(运行时异常)和Checked Exception(检查型异常)。

运行时异常和检查型异常有什么区别?

运行时异常(RuntimeException)是程序逻辑编写不对造成的,如空指针异常、数组索引越界异常,属于代码Bug,应修复代码。检查型异常(Checked Exception)是程序逻辑的一部分,如IO异常、文件找不到异常,必须捕获处理或声明抛出,否则编译失败。

try-catch-finally中finally的执行时机是怎样的?

finally代码块总是在try退出时执行,包括:无异常正常执行、有异常未捕获、有异常被捕获、try中return、catch中return等情况,finally都会执行。

如何指定方法抛出的异常?

如果方法抛出检查型异常且当前方法不适合处理,需要在方法声明中添加throws语句,列出可能抛出的异常,多个异常用逗号分隔。throws语句放在方法名和参数列表之后,方法体左括号之前。

一个catch块可以处理多种异常吗?

可以。Java 7之后,一个catch块支持处理多种类型的异常,语法为catch (ExceptionType1 | ExceptionType2 e),当异常处理逻辑一致时可减少重复代码。

🏷️

标签

➡️

继续阅读