Java7多异常处理

7
我一直在试图找到这个问题的答案,但没有得到令人满意的解释。以下是一些背景:
Java 7允许我们在单个catch块中捕获多个异常,前提是这些异常来自不同的层次结构。例如:
try {
    // some code

} catch(SQLException | FileNotFoundException e) {
    e.printStackTrace();
} catch(Exception e) {
    e.printStackTrace();
}

但如果异常来自同一层次结构,我们必须使用多个 catch 块,例如:
try {
    // some code
} catch(FileNotFoundException  e) {
    e.printStackTrace();
} catch(IOException e) {
    e.printStackTrace();
}

但是如果我尝试编写以下代码,编译器会抱怨说“异常 FileNotFoundException 已经被替代的 IOException 捕获了”。
try {
    // some code
} catch(FileNotFoundException | IOException  e) { // compiler error
    e.printStackTrace();
}

现在我的问题是:为什么编译器在最后一个情况报错,难道它不能发现 FileNotFoundExceptionIOException 的特殊情况吗?如果可以的话,当我的异常处理逻辑相同时,这将避免代码重复。

如果你正在处理 IOException,那么就不需要为 FileNotFoundException 使用相同的处理程序块。 - atish shimpi
3个回答

13

为什么编译器在最后一种情况下报错,它不能弄清楚 FileNotFoundExceptionIOException 的特殊情况吗?

因为 FileNotFoundExceptionIOException 的子类。换句话说,“FileNotFoundException |” 部分是多余的。

以下代码之所以没问题...

} catch(FileNotFoundException  e) {
    ...
} catch(IOException e) {
    ...
}

这是因为在这里,IOException 子句很重要:例如,如果抛出了 SocketException,它会通过 FileNotFoundException 部分,并被 IOException 子句捕获。


0
在捕获异常时,你需要按照从最具体到最一般的顺序排列你的catch子句。
考虑以下层次结构:
class MyException extends Exception {}

class MySubException extends MyException  {}

如果你的代码的一部分抛出了MyException,而另一部分抛出了MySubException,那么你必须先捕获MySubException。
catch(MySubException e){

} catch(MyException e){

}

这与使用 instanceof 运算符是一样的。

如果你测试 MySubException 的一个实例是否是 MyException 的一个实例,结果将会是 true。

mse = new MySubException();

if(mse instanceof MyException){
    println("MyException");
} else if(mse instanceof MySubException){
    println("MySubException");
}

这段代码永远不会打印出"MySubException"。
mse = new MySubException();

if(mse instanceof MySubException){
    println("MySubException");
} else if(mse instanceof MyException){
    println("MyException");
}

这将是正确的顺序。


0

这是因为FileNotFoundException继承了IOException,正如你所说它们处于同一层级,你不能将它们添加到同一个catch块中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接