Re: Incorrect "variable might not have been initialized"
Lee Fesperman wrote:
Sun's 1.4 javac gave me a "variable might not have been initialized"
error on the code below ... when it shouldn't have.
The compiler is correct. The JLS lays down very specific rules for when a
variable is deemed to be "definitely initialised", and your code doesn't
satisfy those conditions. See JLS Section 16.
I know that "ref" /will/ have been initialised, and so do you, but that has
nothing to do with the rules which define the compiler's behaviour.
I don't have 1.5 installed. Could someone try it on 1.5 for me?
I've just checked (JDK 1.5.0_06-b05), same thing happens.
If Test120 works on 1.5, try this one:
Also rejected.
Lastly, this one works on 1.4 but not 1.2, so Sun seems to be making
progress in this area:
public class Test122
{
public static void main(String[] args)
{
boolean retain ;
String ref ;
if (retain = 1 > 0 && (ref = System.getProperty("user.home")) != null)
System.out.println(ref) ;
}
}
After constant-folding "1 > 0", the compiler interprets that as:
if (retain = ( (ref = System.getProperty("user.home")) != null ))
System.out.println(ref);
and, correctly, is quite happy with it. Add extra brackets to change the
meaning:
if ((retain = 1 > 0) && (ref = System.getProperty("user.home")) != null)
System.out.println(ref) ;
and the compiler...
... accepts it !
I believe that to be incorrect under the rules for definite assignment (Section
16.1.1 -- Boolean constant expressions), since I don't believe that
(retain = true)
is a "Boolean constant expression" under the rules (Section 15.28). If [I'm
wrong and] it /is/ considered to be a constant expression, then the rules do
require the compiler to treat "ref" as definitely assigned.
Another example where the compiler (wrongly IMO) treats an assignment as a
constant expression:
int number ;
String ref ;
if (((number = 6) > 0) && (ref = System.getProperty("user.home")) != null)
System.out.println(ref) ;
So at least it's consistent ;-) Maybe the JLS (I'm looking at version 3)
should be changed. Whatever it is /intended/ to mean, it doesn't seem to
consider this case specifically, and I think it should.
-- chris