We know, that if if statement's boolean expression/condition contains compile-time constant (or a variable, holding compile-time constant), then compiler can resolve this constant expression and:
public void ctc1() {
final int x = 1;
String text;
if (x > 0) text = "some text";
System.out.println(text); //compiles fine, as compile-time constant is resolved during compilation phase;
}
would compile and work fine, without "variable might not have been initialized" compiler error. No initialisation of text in "else" branch (or after "if") is required, as compiler "understands" the constant is always going to result in true, while evaluating x > 0 (which ends up being 1 > 0).
Why, however, same resolution does not work (or works differently) when we want to return from the method, as:
public int ctc2() {
final int x = 1;
if (x > 0) return 1;
//requires another explicit "return" for any other condition, than x > 0
}
or, moreover, as:
public int ctc2() {
final int x = 1;
if (1 > 0) return 1;
}
?
Why compiler cannot infer/understand/resolve absolutely identical semantics and cannot be sure, that the return is always executed and code is OK to be compiled?
In case of initialisation in the branch containing compile-time constant, compiler can resolve the constant value(s), and as it knows they will never change, it is sure, variable is going to be initialised. So, it allows usage of the variable after if statement.
Why resolving constant expression works differently for the return case, though? what is the point behind this difference/limitation?
To me, this looks like "two identical logical semantics" work differently.
I'm using:
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)