我正在尝试弄清楚这段代码的内部工作原理。
public void method() {
int x;
try {
x = 10;
} catch(Exception e) {
throw new RuntimeException(); //commenting out this line causes error
}
System.out.println("x: " + x);
}
[当我注释掉第6行时,我在第8行收到了一个编译错误,可能是x尚未初始化。当我将throw语句保留在catch块内时,不会出现此类错误。这有什么不同?从我的角度来看,您可以在try块内初始化变量,然后在外部使用该值,或者不能。无论如何,实际上实际上不会引发任何异常,因为从未输入过catch块。当然,抛出异常的可能性不会导致编译器允许否则会违反Java语法,对吗?
查看简单代码:
int x;
System.out.println(x);
编译器检测到变量x
可能在引用点尚未初始化,因此会引发编译错误。现在来看您的示例,编译器可以肯定有两条路径可以执行该代码:执行try块或执行catch块(对于后者,也可以部分执行try块)。在第二种情况下,x
变量将不会初始化,并且编译器无法生成明智的字节码指令。但是,使用catch块中的throws
时,此代码的执行将停止并且永远不会达到x
的使用率,从而解决了编译器未初始化的变量问题。
包括另一个可能更容易理解的示例:
int x;
if(someCondition()) {
x = 1;
} else {
// x is not initialized through this code path.
}
System.out.println(x); // x may be initialized here, but it is not guaranteed, so this causes a compile error.
我不能说try
内是否可能发生任何真正的例外–可能会发生类似OutOfMemoryError
的事情,但不会被OutOfMemoryError
抓住–但是我相信这仅仅是由于编译器要格外小心(可能不必要)。
catch (Exception e)
块内的行不会引发异常与无关紧要。相反,它评估的是,如果(以某种方式)在try
语句内引发异常,并且随后允许执行继续通过try
子句,则catch
将处于未初始化状态。
确切的答案很可能埋在Java语言规范中,可能埋在x
或14.21. Unreachable Statements中。