为什么不捕获Exception catch RuntimeException?
这对我来说很奇怪。 RuntimeException
inheritance自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