这对我来说很奇怪。 RuntimeException
继承自Exception
,继承自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)
,我认为由于继承而导致语法错误?
答案 0 :(得分:111)
问题的前提是有缺陷的,因为抓住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
的任何内容(如果它是集合而不是数组)也许这就是你所看到的?
答案 1 :(得分:23)
catch (Exception ex) { ... }
将捕获RuntimeException。
无论你在catch块中放入什么,都会被捕获,以及它的子类。
答案 2 :(得分:8)
抓取Exception
会抓住RuntimeException
答案 3 :(得分:3)
我遇到了类似的情况。之所以发生这种情况,是因为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
也会捕获运行时异常。
答案 4 :(得分:-2)
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双向飞碟,@ Jan Zyka