In a recent related question I found that the following code
public static void main(String[] args) {
/*1*/ int x;
/*2*/ boolean found = false;
/*3*/ if (!found)
/*4*/ x = -1;
/*5*/ System.out.println(x);
}
has the compiler error that x isn't init.(initialized). I am amazed that the compiler isn't able to reason the init. especially since this code doesn't seem to require any runtime reasoning as follows:
found
is set false
.!found
is necessarily true
so init is inevitable.I wonder if this is correct. I vaguely remember that compiler optimization can change the order in which statements are executed. Does that play a role here? Is it possible that line 5 is being reached before lines 3 and 4?
Env.
openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment (build 15.0.2+7-27)
OpenJDK 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
javac 15.0.2
Windows 10
See my (late) answer on the other question. The source-code analysis is required by specification.
It's not a case of code reordering in the manner you suggest; that would change behavior, which is forbidden.
Think of the general case: if use of computation was allowed before that computation had been done, then nothing is predictable.
However, in your example here, a sufficiently-smart compiler is allowed to optimize the generated code to (effectively) System.out.println(-1)
. Neither variable is actually necessary.
If such a thing occurred, it would not affect the required checking for definite assignment. Logically, simplification happens after validating the source code.
You'd have to examine the generated byte-code to see what actually happened. Further, in Java the optimization could be done 'later' by just-in-time compilation to native code.