这可能看起来像一个编程101问题,我以为我知道答案,但现在发现自己需要再次检查。在下面这段代码中,第一个捕获块中抛出的异常会被下面的通用异常捕获块捕获吗?
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
我一直认为答案是否定的,但现在我有一些奇怪的行为可能是由这引起的。大多数语言的答案可能都是一样的,但我用的是Java。
不。这很容易检查。
public class Catch {
public static void main(String[] args) {
try {
throw new java.io.IOException();
} catch (java.io.IOException exc) {
System.err.println("In catch IOException: "+exc.getClass());
throw new RuntimeException();
} catch (Exception exc) {
System.err.println("In catch Exception: "+exc.getClass());
} finally {
System.err.println("In finally");
}
}
}
应该打印:
In catch IOException: class java.io.IOException
In finally
Exception in thread "main" java.lang.RuntimeException
at Catch.main(Catch.java:8)
从技术上讲,这可能是编译器错误、依赖于实现、未指定的行为或其他原因。然而,JLS已经被很好地固定下来了,而且编译器已经足够好来处理这类简单的事情(泛型的极端情况可能是另一回事)。
还要注意,如果你在两个catch块之间交换,它不会编译。第二个目标是完全无法达到的。
注意,即使执行了catch块,finally块也始终运行(除了一些愚蠢的情况,例如无限循环、通过工具接口附加并杀死线程、重写字节码等)。