I want to know the difference between Boolean.TRUE
and true
values inside an if
clause. Why does it give me a compilation error (that a value may not have been initialized) when I use Boolean.TRUE
instead of true
.
Below is my code :
public class Test {
public void method1() {
int x;
if(Boolean.TRUE) {
x = 200;
}
System.out.println("x: " + x); // Compilation error
}
public void method2() {
int x;
if(true) {
x = 200;
}
System.out.println("x: " + x); // Compiles fine
}
}
Short answer
For if (true)
the compiler can deduce that x
has been initialized before it's being read. This does not hold for the if (Boolean.TRUE)
case.
Formal answer:
All local variables must have a definite assignment before being read (14.4.2. Execution of Local Variable Declarations):
[...] If a declarator does not have an initialization expression, then every reference to the variable must be preceded by execution of an assignment to the variable, or a compile-time error occurs by the rules of §16.
In this case there's an if
statement involved in the code preceding the reference to the variable, so the compiler performs some flow analysis. However, as spelled out in Chapter 16. Definite Assignment:
Except for the special treatment of the conditional boolean operators
&&
,||
, and? :
and of boolean-valued constant expressions, the values of expressions are not taken into account in the flow analysis.
So since true
is a boolean-valued constant expression and Boolean.TRUE
(which is a reference to a value on the heap, subject to auto-unboxing etc) is not it follows that
if (true) {
x = 200;
}
yields a definite assignment of x
while
if (Boolean.TRUE) {
x = 200;
}
does not.
The difference exists because one is a true constant while the other is just mimicking one.
The compiler will look at things like if
statements and try to figure out whether they will always be a given expression (== true
, == false
, == null
, etc) but it will only do this up to a certain level.
In the case of true
there is no ambiguity: it will always undoubtedly represent "true". However Boolean.TRUE
is just a field, which is apparently not as far as the compiler is willing to go.
public static final Boolean TRUE = new Boolean(true);
Think for example about what would be done if reflection is involved.
You can see this clearly when you introduce an extra level of complexity:
public static void main(String[] args) {
int x;
if(getCondition()) {
x = 5;
}
System.out.println(x);
}
private static boolean getCondition(){
return true;
}
Even though the expression will always be true, the compiler still complains that x
might be unassigned. Only the most rudimentary verification is done to help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With