为什么不捕获Exception catch RuntimeException?

dje*_*lin 40 java exception runtimeexception

这对我来说很奇怪. RuntimeException继承自Exception,继承自Throwable.

catch(Exception exc) { /* won't catch RuntimeException */
Run Code Online (Sandbox Code Playgroud)

catch(Throwable exc) { /* will catch RuntimeException */
Run Code Online (Sandbox Code Playgroud)

我知道这RuntimeException是特别的,因为它没有被检查.但据我所知,这仅适用于是否必须声明例外,而不是它们是否被捕获.即便如此,我也不知道为什么这个逻辑会在捕获Throwable时破坏.

这与我非常相关,因为我遇到了可以在终端操作中抛出RuntimeExceptions的情况.我不确定这个模式的名称,但类似的,我的类EmailRoller需要一个数组Callbacks.代码如下所示:

for(Callback cb : callbacks) {
    try {
        cb.call(item);
    }
    catch(Exception exc) {
        logger.error("Error in callback: ", exc);
   }
}
Run Code Online (Sandbox Code Playgroud)

所以这是一个像OOME这样的东西需要通过的情况,因为如果其中一个回调消耗所有的机器内存,那肯定会影响其他的运行.但是一个NullPointerException?还是一个IndexOutOfBoundsException?这些会影响回调,但不会阻止其他人运行.

此外,这是一个企业设计.不同的程序员或团队可以添加回调来处理项目,但它们应该彼此隔离.这意味着,作为负责将这些回调相互隔离的程序员,我不应该依赖它们来确保错误不会漏掉.捕捉Exception应该是正确的,但不是因为RuntimeException滑倒.所以我更普遍的问题是:这里有什么好的模式?只是catch(Exception | RuntimeException exc),我认为由于继承而导致语法错误?

Jon*_*eet 118

这个问题的前提是有缺陷的,因为捕Exception RuntimeException.演示代码:

public class Test {
    public static void main(String[] args) {
        try {
            throw new RuntimeException("Bang");
        } catch (Exception e) {
            System.out.println("I caught: " + e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

I caught: java.lang.RuntimeException: Bang
Run Code Online (Sandbox Code Playgroud)

如果出现以下问题,您的循

  • callbacks 一片空白
  • callbacks循环执行时修改的任何东西(如果它是一个集合而不是一个数组)

也许这就是你所看到的?

  • @djechlin:你的帖子没有*显示*`if(results.foo.bar())` - 目前还不清楚你在实际问的是什么...... (6认同)
  • 重读我的代码.那是对的.我的绝缘层是错误的,因为运行时异常来自`if(results.foo.bar()){/*apply callback*/}`,这是一个NPE. (2认同)

Jan*_*yka 23

catch (Exception ex) { ... }
Run Code Online (Sandbox Code Playgroud)

捕获RuntimeException.

无论你在catch块中放置什么,都会被捕获,以及它的子类.


cmd*_*cmd 8

捕获Exception将抓住一个RuntimeException