如何解释Exception是不是会捕获RuntimeException?
Posted
技术标签:
【中文标题】如何解释Exception是不是会捕获RuntimeException?【英文标题】:How to explain whether Exception will catch RuntimeException?如何解释Exception是否会捕获RuntimeException? 【发布时间】:2013-10-10 10:28:30 【问题描述】:这对我来说很奇怪。 RuntimeException
继承自Exception
,后者继承自Throwable
。
catch(Exception exc) /* won't catch RuntimeException */
但是
catch(Throwable exc) /* will catch RuntimeException */
我知道RuntimeException
的特殊之处在于它没有被选中。但据我了解,这仅适用于是否必须声明异常,而不是它们是否被捕获。即便如此,我也不知道为什么这个逻辑会在捕获Throwable
时中断。
这与我非常相关,因为我有一种情况,可以在终端操作中抛出 RuntimeException
。我不确定这种模式的名称,但类似于我的课程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)
,我认为是因为继承的语法错误?
【问题讨论】:
您应该编辑问题标题 - 如果有人只看标题,他们会认为捕获异常不会捕获运行时异常。 @AlexCiminian 好点。这是另一个 8 年的信息性问题! 【参考方案1】:catch (Exception ex) ...
将捕获 RuntimeException。
无论你放在 catch 块中的什么东西都会被捕获,它的子类也会被捕获。
【讨论】:
【参考方案2】:问题的前提是有缺陷的,因为捕捉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
(如果它是一个集合而不是一个数组)
也许这就是你所看到的?
【讨论】:
重读我的代码。这是正确的。我的绝缘层有问题,因为运行时异常来自if(results.foo.bar()) /* apply callback */
,这是一个 NPE。
@djechlin:你的帖子没有显示 if (results.foo.bar())
- 目前还不清楚你实际上在问什么......
查看我下面的帖子,Exception 没有捕获运行时异常。【参考方案3】:
捕获Exception
将捕获RuntimeException
【讨论】:
【参考方案4】:我遇到了类似的情况。这是因为 classA 的初始化依赖于 classB 的初始化。当classB 的静态块遇到运行时异常时,classB 没有被初始化。因此classB没有抛出异常,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
也会捕获运行时异常。
【讨论】:
【参考方案5】: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 ,因此它不处理运行时异常。 @jon skeet,@Jan Zyka
【讨论】:
抛出 RuntimeException 的线程不是试图捕获异常的线程。这与它是否是 RuntimeException 无关。您的main
方法已成功中断线程,所以 that try
块没有什么可捕获的。然后有一个单独的RuntimeException
被抛出堆栈并且没有被任何东西(在用户代码中)捕获,因为没有任何东西in堆栈可以捕获它。以上是关于如何解释Exception是不是会捕获RuntimeException?的主要内容,如果未能解决你的问题,请参考以下文章
如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)
JAVA捕获MYSQL主键冲突异常 示例如Exception ex 对应的异常 如何捕获,只要捕获,求满意答案