Java7多重异常处理
我一直试图找到这个问题的答案,但没有得到任何令人满意的解释。以下是一些背景: Java7允许我们在单个catch块中捕获多个异常,前提是这些异常来自不同的层次结构。例如: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(); } 但如果异常来自同一层次结构,
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");
}