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

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

我发现了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

java eclipse exception-handling initialization
2个回答
5
投票

好问题,它也多次困扰我。

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

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

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


1
投票

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

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

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

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