Java基础篇-深入理解异常的抛出与处理
深入理解异常的抛出与处理
一、异常的抛出
(一)系统自动抛出异常
在程序执行过程中,当遇到一些不符合语言规则或者逻辑错误的情况时,Java 系统会自动抛出异常。例如,进行整数除法运算时,如果除数为 0,系统就会自动抛出 ArithmeticException 异常。
1 | public class AutoThrowException { |
在上述代码中,10 / 0 这一操作不符合数学运算规则,Java 系统检测到这个错误后,会自动创建一个 ArithmeticException 异常对象并抛出。此时,程序的正常执行流程被打断,不会继续执行 System.out.println("结果是: " + result); 这一行代码。
(二)手动抛出异常
有时候,根据业务逻辑的需要,程序员需要手动抛出异常。这通过 throw 关键字来实现。例如,在一个用户注册功能中,要求用户名不能为空。如果检测到用户名为空,就可以手动抛出一个自定义异常。
1 | class UsernameEmptyException extends RuntimeException { |
在 registerUser 方法中,通过 if 语句检查用户名是否为空。如果为空,使用 throw 关键字手动抛出一个 UsernameEmptyException 异常对象。这个异常对象携带了 “用户名不能为空” 这一错误信息。
二、异常的声明抛出
当一个方法内部可能会抛出某种异常,但该方法本身不处理这个异常,而是希望调用它的方法来处理时,就需要在方法声明中使用 throws 关键字声明该方法可能抛出的异常类型。
1 | import java.io.FileNotFoundException; |
在 readFile 方法中,FileReader 的构造函数可能会因为文件不存在而抛出 FileNotFoundException 异常。由于 readFile 方法不处理这个异常,所以在方法声明处使用 throws FileNotFoundException 声明。这样,调用 readFile 方法的代码(如 main 方法)就需要处理这个可能抛出的异常,否则会导致编译错误。
三、异常的捕获与处理
为了避免异常导致程序终止运行,需要使用 try - catch 块来捕获并处理异常。
(一)基本的 try - catch 结构
1 | public class BasicTryCatch { |
在 try 块中放置可能会抛出异常的代码。如果 try 块中的代码抛出了 ArrayIndexOutOfBoundsException 异常,程序会立即跳转到对应的 catch 块中执行。catch 块中的参数 e 是捕获到的异常对象,可以通过它获取异常的相关信息,如错误消息。处理完 catch 块中的代码后,程序会继续执行 try - catch 块之后的代码。
(二)多重 catch 块
当 try 块中的代码可能抛出多种不同类型的异常时,可以使用多个 catch 块来分别处理不同类型的异常。
1 | public class MultipleCatch { |
在这个例子中,try 块中的代码既有可能抛出 ArithmeticException 异常(除法运算中除数为 0),也有可能抛出 ArrayIndexOutOfBoundsException 异常(数组越界访问)。每个 catch 块负责处理特定类型的异常,程序会根据实际抛出的异常类型跳转到对应的 catch 块执行。
(三)finally 块
finally 块通常与 try - catch 块一起使用,无论 try 块中是否抛出异常,也无论异常是否被 catch 块捕获,finally 块中的代码都会被执行。
1 | public class FinallyBlock { |
在上述代码中,try 块正常执行没有抛出异常,但 finally 块中的代码依然会被执行。如果 try 块中抛出了异常并且被 catch 块捕获,finally 块同样会在 catch 块执行完毕后执行。
通过理解异常的抛出、声明抛出以及捕获处理机制,可以更好地编写健壮的 Java 程序,使其能够应对各种可能出现的错误情况,提高程序的稳定性和可靠性。
-
感谢你赐予我前进的力量