I was trying to come up with obscure test cases for an alternative open-source JVM I am helping with (Avian) when I came across an interesting bit of code, and I was surprised that it didn't compile:
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();
}
}
The most obvious code path (the only one that I see) is to execute a = 1, "attempt" to return a (the first time), then execute the finally, which actually returns a. However, javac complains that "a" might not have been initialized:
Test.java:8: variable a might not have been initialized return a; ^
The only thing I can think of that might cause / allow a different code path is if an obscure runtime exception were to occur after the start of the try but before the value 1 is assigned to a - something akin to an OutOfMemoryError or a StackOverflowException, but I can't think of any case where these could possibly occur at this place in the code.
Can anyone more familiar with the specifics of the Java standard shed some light on this? Is this just a case where the compiler is being conservative - and therefore refusing to compile what would otherwise be valid code - or is something stranger going on here?