MENU

异常的捕获与处理

June 19, 2018 • Read: 3472 • Java阅读设置

try catch 格式

  • try{
  • //可能产生异常的语句
  • }catch{
  • ......
  • }catch{
  • ......
  • }finally{
  • ......
  • }
  • try 代码后跟一个或多个 catch 代码段
  • 每个 catch 代码段声明其能处理的一种特定类型的异常,并提供处理方法
  • 当异常发生时,程序会中止当前的流程,根据获取异常的类型去执行相应的 catch 代码段
  • finally 段的代码,无论是否发生异常,都会执行

上图左边,语句 1 发生异常,就会被捕获,跳转到相应的 catch 语句里,语句 2 并不会执行

总结 try 语句

  • try {...} 语句指定了一段代码,该段代码就是一次捕获并处理异常的范围
  • 在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的 catch 语句要分别对这些异常做相应的处理
  • 如果没有异常产生,所有的 catch 代码段都被忽略不执行

总结 catch 语句

  • catch 语句块里的代码是对异常进行处理的,每个 try 语句块可以伴随一个或多个 catch 语句,用于可能产生的不同类型的异常对象
  • 在 catch 语句中声明的异常对象 (catch (SomeException e)) 封装了异常事件发生的信息,在 catch 语句块中可以使用这个对象的一些方法获取这些信息
  • 例如:

    • getMessage () 方法,用来得到有关异常事件的信息
    • printStackTrace () 方法,用来跟踪异常事件发生时执行的堆栈内容

总结 finally 语句

  • finally 语句为异常处理提供一个统一的出口,使得在控制流程转到其他的部分以前,能够对程序的状态作统一管理
  • 无论 try 所制定的代码块中是否抛出异常,finally 语句所指定的代码块都要执行
  • 通常在 fianlly 语句中可以执行资源的清除工作,例如:

    • 关闭打开的文件
    • 删除临时文件
  • import java.io.FileInputStream;
  • import java.io.FileNotFoundException;
  • import java.io.IOException;
  • public class Test{
  • public static void main(String[] args) {
  • FileInputStream in = null;
  • try {
  • in = new FileInputStream("MyFile.txt");
  • int b;
  • b = in.read();
  • while(b != -1) {
  • System.out.println((char)b);
  • b = in.read();
  • }
  • }catch(FileNotFoundException e){
  • e.printStackTrace();
  • }catch(IOException e) {
  • e.getMessage();
  • }finally {
  • try {
  • in.close();
  • }catch(IOException e){
  • e.printStackTrace();
  • }
  • }
  • }
  • }

上述代码有一个细节要注意,如果将 IOException 和 FileNotFoundException 交换位置,编译时会报错,因为 IOException 包含 FileNotFoundException,所以在 IOException 时已经捕获了异常,但是下面 FileNotFoundException 又会捕获一次异常,很不合理。捕获异常时,先捕获小的,再捕获大的,如果两个异常并列,顺序无所谓

声明方法抛出的异常

  • import java.io.FileInputStream;
  • import java.io.FileNotFoundException;
  • import java.io.IOException;
  • public class Test{
  • public static void main(String[] args) {
  • }
  • void m(int i) throws ArithmeticException{
  • if(i == 0)
  • throw new ArithmeticException("除数不能为0");
  • }
  • void f() throws IOException,FileNotFoundException{
  • FileInputStream in = null;
  • int b;
  • b = in.read();
  • while(b != -1) {
  • System.out.println((char)b);
  • b = in.read();
  • }
  • }
  • void f2() throws Exception {
  • f();
  • }
  • }

在当前函数抛出的异常,并不知道应该如何处理,就先将其抛出,由谁使用就由谁处理,如果使用者也不知道,就继续抛出

许多 java 库中的函数也有抛出异常,例如:
上述两个是 java.io 包中对文件进行操作的函数,他们自己本身就有异常要抛出,所以在使用的过程中要么 catch,要么继续 throws

自定义异常类

  1. 通过继承 java.lang.Exception 类声明自己的异常类
  2. 在方法适当的位置生成自定义异常的实例,并用 throws 语句抛出
  3. 在方法的声明部分用 throws 语句声明该方法可能抛出的异常
  • class MyException extends Exception{
  • private int id;
  • public MyException(String message,int id){
  • super(message);
  • this.id = id;
  • }
  • public int getId(){
  • return id;
  • }
  • }

一些小问题

  1. 重写方法需要抛出与原方法所抛出异常类型一直的异常,或不抛出异常
  • class A{
  • public void method() throws IOException{...}
  • }
  • class B1 extends A{
  • public void method() throws FileNotFoundException{...}//Error
  • }
  • class B2 extends A{
  • public void method() throws Exception{...}//Error
  • }
  • class B3 extends A{
  • public void method(){...}//Right
  • }
  • class B4 extends A{
  • public void method() throws IOException,MyException{...}//Error
  • }

总结

  • 一个图
  • 五个关键字

    • try、catch、finally、throws、throw
  • 先捕获小的,再捕获大的
  • 异常和重写的关系
Last Modified: May 12, 2021
Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment