Eclipse不认为System.exit会中断执行

时间:2012-09-22 18:18:17

标签: java eclipse exception-handling initialization

我发现Eclipse报告“局部变量可能尚未初始化”错误的方式存在奇怪的二分法。如果我在try / catch块之外声明一个变量,在try / catch块中初始化它,然后在try / catch块之后使用它,通常会发生此错误:

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    e.printStackTrace();
}
r.nextInt(); //Error: The local variable r may not have been initialized

这是有道理的。我可以通过在声明它时将变量初始化为null来避免错误,通过确保程序的控制流永远不会到达下一个语句(如果try / catch中发生异常)块。因此,如果变量初始化失败,我真的无法继续执行,我可以这样做:

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    throw new RuntimeException("Initialize secure random number generator failed");
}
r.nextInt(); //No error here

但是,我最近尝试使用System.exit来停止程序而不是RuntimeException来使程序的控制台输出更清晰。我认为这些都是等价的,因为两者都阻止程序继续执行,但我发现Eclipse不同意:

Random r;
try {
    r = new AESCounterRNG();
} catch (GeneralSecurityException e) {
    System.err.println("Couldn't initialize secure random number generator");
    System.exit(1);
}
r.nextInt(); //Error: The local variable r may not have been initialized

如果发生异常,执行永远无法达到r.nextInt(),为什么Eclipse仍然会给我“未初始化”错误?这是Eclipse中的错误,还是某种方式即使在调用r.nextInt()之后执行仍可继续System.exit

2 个答案:

答案 0 :(得分:5)

好问题,它也多次惹我生气。

问题在于,抛出一个异常,只是调用一个方法(那就是System.exit(1);)通常不能保证程序流程停止。当然,the documentation of System.exit()说这种方法永远不会正常返回。但是虽然throw的语义是由语言本身定义的,但System.exit()的语义只是在Javadoc中。

我的猜测是,他们还没有费心去实施这个特殊情况。虽然有一个错误报告,其中涉及该主题(https://bugs.eclipse.org/bugs/show_bug.cgi?id=126551,请参阅注释2),但它被标记为“不会修复”,因为它似乎太复杂了。

编辑:正如rlegendi指出的那样,它实际上是Java编译器的一个问题,而不仅仅是Eclipse。到目前为止,我的解决方案是使用普通的throw,(而不是一些特殊的throw()方法),除了非常小的应用程序之外,其他任何东西都优于System.exit()

答案 1 :(得分:1)

这不是一个错误:在你的第二个例子中,保证在调用站点初始化r(否则抛出一个exeption,以便关闭执行分支)。

在第一个和第三个例子中,您只需执行程序代码并保持r未定义。如果您在异常处理区或声明处为其分配null,则不会抱怨。

顺便说一下,这不是Eclipse问题,JLS定义您不能使用未初始化的变量。尝试用Java编译它,你应该得到完全相同的输出。