为什么不捕获Exception catch RuntimeException?

这对我来说很奇怪。 RuntimeExceptioninheritance自Exception ,它inheritance自Throwable

 catch(Exception exc) { /* won't catch RuntimeException */ 

 catch(Throwable exc) { /* will catch RuntimeException */ 

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

这与我非常相关,因为我有一种情况,可以在终端操作中抛出RuntimeExceptions。 我不确定这个模式的名称,但是类似于我的类EmailRoller采用了一系列Callbacks 。 代码如下所示:

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

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

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

这个问题的前提是有缺陷的,因为捕获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); } } } 

输出:

 I caught: java.lang.RuntimeException: Bang 

如果出现以下问

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

也许这就是你所看到的?

 catch (Exception ex) { ... } 

捕获RuntimeException。

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

捕获Exception将捕获RuntimeException

我遇到了类似的情况。 之所以发生这种情况,是因为classA的初始化依赖于classB的初始化。 当classB的静态块面临运行时exception时,classB未初始化。 因此,classB没有抛出任何exception,classA的初始化也失败了。

 class A{//this class will never be initialized because class B won't intialize static{ try{ classB.someStaticMethod(); }catch(Exception e){ sysout("This comment will never be printed"); } } } class B{//this class will never be initialized static{ int i = 1/0;//throw run time exception } public static void someStaticMethod(){} } 

是的…捕获Exception也会捕获运行时exception。

 class Test extends Thread { public void run(){ try{ Thread.sleep(10000); }catch(InterruptedException e){ System.out.println("test1"); throw new RuntimeException("Thread interrupted..."+e); } } public static void main(String args[]){ Test t1=new Test1(); t1.start(); try{ t1.interrupt(); }catch(Exception e){ System.out.println("test2"); System.out.println("Exception handled "+e); } } } 

它的输出不包含test2,因此它不处理运行时exception。 @jon双向飞碟,@ Jan Zyka