Java7多重异常处理

Java7多重异常处理,java,exception-handling,java-7,Java,Exception Handling,Java 7,我一直试图找到这个问题的答案,但没有得到任何令人满意的解释。以下是一些背景: Java7允许我们在单个catch块中捕获多个异常,前提是这些异常来自不同的层次结构。例如: try { // some code } catch(SQLException | FileNotFoundException e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); } 但如果异常来自同一层次结构,

我一直试图找到这个问题的答案,但没有得到任何令人满意的解释。以下是一些背景:

Java7允许我们在单个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
捕获。”

现在我的问题是:为什么编译器在最后一种情况下报告一个错误,它不能指出
FileNotFoundException
IOException
的特例吗?当我的异常处理逻辑相同时,这将节省代码重复

为什么编译器在最后一种情况下报告错误,难道它不能指出
FileNotFoundException
IOException
的特例吗

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

下面代码正常的原因是

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

…因为这里的
IOException
子句很重要:例如,如果抛出
SocketException
,它将通过
FileNotFoundException
部分传递,并被捕获在
IOException
子句中。

捕获异常时,您必须从最具体的到最一般的顺序排列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”


这将是正确的顺序。

因为FileNotFoundException扩展了IOException,正如您所说,它具有相同的层次结构,您不能将它们添加到同一个catch块。

如果您正在处理
IOException
,则无需对
FileNotFoundException使用相同的处理程序块。
mse = new MySubException();

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

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