Reputation: 883
Why is x not initialized in the following ?
public class rough {
public static void main(String[] args) {
int x;
boolean found = false;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.5) {
found = true;
x = 10;
break;
}
}
if (!found)
x = -1;
System.out.println(x);//x isn't initialized here
}
}
On average, for half of the iterations, the if
inside the for loop would be true
, thus initializing x
. For the other half, found
stays false
therefore the outer if
would initialize. Therefore, I don't understand why the compiler is annoyed.
As the ultimate distillation (see successive simplifications below), consider
public static void main(String[] args) {
int x;
boolean found = false;
if (!found)
x = -1;
System.out.println(x);
}
which also gives the error that x
isn't init.
previous simplifications
Even more surprisingly, changing
if (Math.random() < 0.5)
to if(true)
also has the same problem.
In fact, investigating further, replacing the original for
loop by these
for (int i=0;i<1;i++)
x = 10;
for (; !found; ) {
x = 10;
break;
}
is equally worse. Only for(;;){... break;}
& for(;true;){... break;}
don't raise any init. errors.
Upvotes: 0
Views: 251
Reputation: 1328
(Writing this up as a separate answer since I think it'll benefit from being taken out of comments).
This is the language-lawyer's answer.
The language specification requires initialization of variables before they are used.
The rules include:
The variable must be given a value on all possible paths through the code. The specification refers to this as 'definite assignment'.
The compiler does not consider the values of expressions in this analysis. See Example 16.2 for this.
The second rule explains why even in cases that are 'obvious' to us, the compiler can't use that knowledge. Even if the compiler-writer cared to do a deeper analysis, adherence to the Java specification forbids it.
If the next question is 'but why?' then I'd have to guess, but the point of a standard is to get consistent behaviour. You don't want one compiler accepting as legal Java something that another compiler rejects.
Upvotes: 1
Reputation: 201447
The compiler can't easily detect all branches lead to x
being initialized, but you can fix that (and the code) pretty easily by assigning -1
to x
to begin with. Something like
public static void main(String[] args) {
int x = -1;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.5) {
x = 10;
break;
}
}
System.out.println(x);
}
And now you don't need found
(so I removed it too).
Upvotes: 2