Java catch块中的throw语句如何防止未初始化变量的编译器错误?
我试图找出这段代码的内部工作原理Java catch块中的throw语句如何防止未初始化变量的编译器错误?,java,exception,Java,Exception,我试图找出这段代码的内部工作原理 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
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块中的抛出
时,此代码的执行将停止,并且永远无法使用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
中是否有任何真正的异常可能会发生,比如可能会发生,但不会被catch(Exception e)
捕获,但我相信这只是因为编译器格外小心(可能是不必要的)
try
块中的行不抛出异常与此无关。相反,它的计算结果是,如果在try
语句中抛出异常(以某种方式),并且随后允许执行继续通过catch
子句,那么x
将处于未初始化状态
确切答案很可能隐藏在Java语言规范中,可能在或中。什么是Java版本?@NomadMaker Java11@chrylis-onstrike-不,我只得到我提到的一个错误。除非我弄错了,否则这是一个编译时错误,就像放了一个额外的括号或忘记了分号一样,所以这怎么可能被允许呢?只是重复了这个。我还不明白为什么会这样。我想我刚刚弄明白了。中断异常。MemoryError不太可能在堆栈上分配原语。虽然StackOverflower可能会出错。
InterruptedException
可能适合。我同意OutOfMemoryError
不太可能发生-我将上面的措辞从“可能发生”改为“可能发生”。实际上,可能很少有情况下单行x=10
会导致任何类型的异常。在这种情况下,堆栈溢出的问题是这是一个错误,而不是异常。