我正在准备 OCP 考试,我正在使用 Enthuware 。 我有这个问题,编译和运行以下代码的结果是什么?
try {
throw new IOException();
} catch(IOException e) {
throw e;
} finally {
throw new RuntimeException();
}
显然,代码确实编译但是抛出RuntimeException
并且我完全理解为什么。
我只是好奇为什么以下代码无法编译:
try {
throw new IOException();
} catch(IOException e) {
throw e;
} finally {
test();
}
test()
函数的位置如下:
static final void test() throws RuntimeException {
throw new RuntimeException();
}
即使我将test
函数声明为final
,因为我认为编译器可能知道覆盖 ......
有人可以向我解释一下吗?
抱歉英文不好!
- 修改 只是想知道为什么要投票?
错误消息是编译错误:
未处理的异常类型IOException
我尝试编译时的错误消息是:
线程“main”中的异常java.lang.Error:未解决的编译问题: 未处理的异常类型IOException
答案 0 :(得分:0)
第一个代码段编译是因为finally
块在返回值之前运行,或者从方法的非finally
部分抛出异常。您投掷RuntimeException
这一事实意味着您不会投掷您原本应该的IOException
。编译器可以解决这个问题,因此它并不坚持要么声明或捕获IOException
。
但编译器只在执行此检查时一次查看一个方法。因此第二个代码段无法编译,因为编译器不会检查test()
总是 抛出RuntimeException
。相反,它假定test()
可能不抛出RuntimeException
;如果发生这种情况,IOException
将被抛出。因此,编译器坚持要么捕获IOException
,要么在throws
子句中声明它。
答案 1 :(得分:0)
在java中,异常处理具有概念异常传播。
首先从堆栈顶部抛出异常,如果没有捕获,则将调用堆栈下拉到前一个方法,如果没有捕获,则异常再次下降到前一个方法,依此类推直到它们被捕获或直到它们到达调用堆栈的最底部。这称为异常传播。
规则1:默认情况下,未经检查的例外情况会在主叫链中传播(传播)。
规则2:默认情况下,Checked Exceptions不会在调用链中转发(传播)。
try {
throw new IOException();
} catch(IOException e) {
throw e;
} finally {
throw new RuntimeException();
}
在上面的代码片段中,抛出RuntimeException以防止抛出IOException。
try {
throw new IOException();
} catch(IOException e) {
throw e;
} finally {
test();
}
static final void test() throws RuntimeException {
throw new RuntimeException();
}
在上面的代码片段test()方法中抛出RuntimeException但不会阻止抛出IOException。 正如规则2 默认情况下,编译器不会传播Checked Exceptions,因此您必须声明或处理异常。
让我们举例说明如果用 RuntimeException 替换 IOException ,那么它就不会给出编译时错误,因为默认情况下规则1 未经检查异常被转发在调用链(传播)。
try {
throw new RuntimeException();
} catch(RuntimeException e) {
throw e;
} finally {
test();
}
static final void test() throws RuntimeException{
throw new RuntimeException();
}