当我遇到一段有趣的代码时,我试图为我正在帮助的替代开源 JVM ( Avian ) 提出晦涩的测试用例,但我很惊讶它没有编译:
public class Test {
public static int test1() {
int a;
try {
a = 1;
return a; // this is fine
} finally {
return a; // uninitialized value error here
}
}
public static void main(String[] args) {
int a = test1();
}
}
最明显的代码路径(我看到的唯一一个)是执行a = 1,“尝试”返回a(第一次),然后执行finally,它实际上返回a。但是,javac 抱怨“a”可能没有被初始化:
Test.java:8:变量 a 可能尚未初始化 返回一个; ^
我能想到的唯一可能导致/允许不同代码路径的事情是,如果在尝试开始之后但在将值 1 分配给 a 之前发生模糊的运行时异常 - 类似于 OutOfMemoryError 或 StackOverflowException,但我想不出这些可能发生在代码中的这个地方的任何情况。
任何更熟悉 Java 标准细节的人都可以对此有所了解吗?这只是编译器保守的情况 - 因此拒绝编译原本有效的代码 - 还是这里发生了一些奇怪的事情?