catch块中的throw语句如何防止未初始化变量的编译器错误?

问题描述 投票:1回答:2

我正在尝试弄清楚这段代码的内部工作原理。

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语法,对吗?

java exception
2个回答
1
投票

查看简单代码:

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.

1
投票

我不能说try内是否可能发生任何真正的例外–可能会发生类似OutOfMemoryError的事情,但不会被OutOfMemoryError抓住–但是我相信这仅仅是由于编译器要格外小心(可能不必要)。

catch (Exception e)块内的行不会引发异常与无关紧要。相反,它评估的是,如果(以某种方式)在try语句内引发异常,并且随后允许执行继续通过try子句,则catch将处于未初始化状态。

确切的答案很可能埋在Java语言规范中,可能埋在x14.21. Unreachable Statements中。

© www.soinside.com 2019 - 2024. All rights reserved.