在 catch 块中抛出异常 - 它会再次被捕获吗?

新手上路,请多包涵

这看起来像是一个编程 101 问题,我原以为我知道答案,但现在发现自己需要仔细检查。下面这段代码中,第一个catch块中抛出的异常会不会被下面的通用Exception catch块捕获?

 try {
  // Do something
} catch(IOException e) {
  throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
  // Will the ApplicationException be caught here?
}

我一直认为答案是否定的,但现在我有一些可能由此引起的奇怪行为。大多数语言的答案可能是相同的,但我在 Java 中工作。

原文由 roryf 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

不,因为新的 throw 不在 try 块中。

原文由 C. K. Young 发布,翻译遵循 CC BY-SA 2.5 许可协议

不,这很容易检查。

 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");
        }
    }
}

应该打印:

在捕获 IOException: class java.io.IOException
最后在
线程“main”中的异常 java.lang.RuntimeException
        在 Catch.main(Catch.java:8)

从技术上讲,这可能是编译器错误、依赖于实现、未指定的行为或其他原因。然而,JLS 非常明确,编译器对于这种简单的事情来说已经足够好了(泛型极端情况可能是另一回事)。

另请注意,如果您交换两个 catch 块,它不会编译。第二个捕获将是完全无法到达的。

请注意,即使执行了 catch 块,finally 块也会始终运行(愚蠢的情况除外,例如无限循环、通过工具接口附加并终止线程、重写字节码等)。

原文由 Tom Hawtin - tackline 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题