Java多捕获异常示例
在本文中,我们将看到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。