Suppose I have the following piece of code
int myVar;
final boolean condition = <someCondition>;
if (condition) {
myVar = 1;
}
if (condition) {
System.out.println("myVar = " + myVar);
}
When I compiled this, I got the expected myVar might not have been initialized
error. Is this a bug in the compiler? It's easy to see that "myVar" was set when condition
is true, and it is only referenced when condition
is true. ( condition
is also never reset)
PS: To those comments on me needing to init it to 0, yes I am aware of that. But the point is, I wanted "myVar" to be final (ie., value set at most once)
The initialization requirement is a formal part of Java, as described in the JLS:
For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.
( JLS 8, chapter 16 ; emphasis in the original)
The JLS goes on to say
The analysis takes into account the structure of statements and expressions; it also provides a special treatment of the expression operators
!
,&&
,||
, and? :
? :
, and of boolean-valued constant expressions.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 .
(emphasis added)
Note well that condition
being final
does not make it a "constant expression" as the specification defines that term. The specification goes on to give the specific rule for if
statements :
V
is [un]assigned afterif (e) S
iffV
is [un]assigned afterS
andV
is [un]assigned aftere
when [e
evaluates to]false
.
In your particular code, then:
int myVar;
myVar
is definitely un assigned here.
final boolean condition = <someCondition>; if (condition) { myVar = 1; }
myVar
is "assigned after S" because S, the body of the if
statement, performs an unconditional assignment. myVar
is not assigned after evaluation of the condition, however, whether the condition evaluates to true
or false
. Therefore, myVar
is not definitely assigned at this point in the method.
if (condition) {
And nothing has changed at this point: myVar
still is not definitely assigned as far as the JLS rules are concerned, so its value must not be read. The compiler is therefore obligated to report an error in the next statement:
System.out.println("myVar = " + myVar); }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.