Java多捕获异常示例

时间:2020-01-09 10:34:57  来源:igfitidea点击:

在本文中,我们将看到Java 7中添加的新功能Multi-Catch异常。使用Multi-catch语句,单个catch块可以处理多种类型的异常。在异常处理代码相似的情况下,我们无需编写多个catch块即可捕获不同的异常。

Java中的Multi-Catch异常之前

如果代码引发多种类型的异常,那么在Java 7中引入Multi-Catch异常之前,我们将使用多个catch块,每个异常一个。
假设我们正在读取文件,并且文件的每一行都有一个整数。我们将以字符串形式读取文件的每一行,然后将该字符串转换为int。因此,我们需要在代码IOException和NumberFormatException中处理两个异常。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Logger;

public class MultiCatch {
  private final static Logger logger = Logger.getLogger(MultiCatch.class.getName());
  public static void main(String[] args) throws IOException {
    BufferedReader br = null;
    try{
      String strLine;
      br = new BufferedReader(new InputStreamReader(
                             new FileInputStream(new File("D:\test.txt"))));
      while((strLine = br.readLine()) != null){
          System.out.println("Line is - " + strLine);
          int num = Integer.parseInt(strLine);
      }
        
    }catch(NumberFormatException  ex){
      logger.info(ex.getMessage());
      throw ex;			
    }catch(IOException ex){
      logger.info(ex.getMessage());
      throw ex;
    }finally{
      try {
        br.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }		
  }
}

注意这里的一些问题

  • 即使异常处理代码相同,我们也要记录该异常,然后再次将其抛出,但必须有单独的catch块。

  • 由于变量ex具有不同的类型,因此很难创建消除重复代码的通用方法。

  • 我们甚至可能想编写一个带有Exception作为类型的catch块来捕获所有异常,而不是编写多个catch块来捕获特定异常。但这不是一个好习惯。

在Java中使用Multi-Catch异常

从Java 7开始,我们可以使用多捕获异常在一个catch块中捕获多个异常。这样,我们可以避免代码重复,也可以避免将Exception类用作包罗万象的子句的趋势,这将隐藏真正的原因。

Java多捕获异常示例

这里使用多捕获异常编写与上面使用的相同代码

public class MultiCatch {
  private final static Logger logger = Logger.getLogger(MultiCatch.class.getName());
  public static void main(String[] args) throws IOException {
    BufferedReader br = null;
    try{
      String strLine;
      br = new BufferedReader(new InputStreamReader
                      (new FileInputStream
                      (new File("D:\test.txt"))));
      while((strLine = br.readLine()) != null){
        System.out.println("Line is - " + strLine);
        int num = Integer.parseInt(strLine);
      } 
    }catch(NumberFormatException | IOException  ex){
      logger.info(ex.getMessage());
      throw ex;
    }finally{
      try {
        br.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}
  • 现在只有一个合并两个捕获块的捕获块。

  • 在多捕获语句中,我们需要使用竖线(|)分隔catch子句中的每种异常类型。

多捕获语句中使用的捕获参数是最终的

在处理多个异常类型的多catch语句中,catch参数是隐式最终的。在上面的代码中,catch参数ex是最终的,因此我们不能在catch块中为其分配任何值。

多捕获语句生成的字节码更胜一筹

与每个只能处理一种异常类型的多个catch块相比,Java中的multi-catch语句生成的字节码会更小(因此更好)。多重捕获不会在编译器生成的字节码中产生重复。

具有相同类型的异常的Multi-Catch语句

试图在multi-catch语句中捕获相同类型的异常将导致编译时错误。

例如

catch (FileNotFoundException | IOException ex) {
  Logger.error(ex);
}

由于FileNotFoundException是IOException的子类,因此多次捕获会导致编译时错误。我们将收到错误,因为备用IOException已捕获异常FileNotFoundException。