Reputation: 1189
This is the snippet of code in Java language:
public void name(){
int value = 9;
int o;
if(value > 9)
o = 5;
if(value <= 9)
o = 8;
System.out.println(o);
}
Why does compiler can't see the second if statement considering the last option of the value? It won't compile. Best regards
Upvotes: 5
Views: 116
Reputation: 718986
The reason that the original version doesn't compile is that the JLS' "definite assignment" rules in JLS section 16 say that o
has not been definitely assigned. The compiler reports this with an enigmatic message that says that "o
may not have been initialized".
Now, anyone with simple deductive skills can see that the 2nd if
condition is the negation of the 1st if
condition, and therefore the variable will in fact always be initialized. However, the JLS does not allow a compiler to make that deduction. The JLS says this an error ...
There are a number of ways to fix this. For example
o
in the declaration.if
statements with a single if
/ else
statement.value
as final
.The last fix is interesting. The reason it works is that the JLS definite assignment rules require the compiler to take the value of a compile-time constant boolean-valued expression into account.
This statement (with the final
added)
final int value = 9;
means that value
is a compile-time constant. That means that value <= 9
and value > 9
are also compile-time constants. The JLS definite assignment rules therefore state that o
is definitely assigned after
if(value <= 9) o = 8;
and can be used later without a compilation error.
The definite assignment rules are designed to prevent the use of uninitialized variables, and prevent blank final
variables being initialized more than once.
The JLS's conservative treatment of expression values in the definite assignment rules is designed to avoid problems where one Java compiler deduces that something is definitely assigned, but another cannot. The subcase of compile-time-constant expressions can be handled by simply evaluating the expression, and the JLS rules implicitly recognize this.
Upvotes: 1
Reputation: 12510
As per JLS (§16) every local variable and non-blank field must be definitely assigned before it can be used. The compiler does some basic static analysis to ensure it.
The idea behind definite assignment is that an assignment to the local variable or blank final field must occur on every possible execution path to the access. Similarly, the idea behind definite unassignment is that no other assignment to the blank final variable is permitted to occur on any possible execution path to an assignment.
The static analyzer can only deduce values of constant expressions ($15.28) which is not the case in your example.
Upvotes: 0
Reputation: 726699
The compiler must treat value
as changeable unless you say otherwise. Declaring it final
fixes the problem:
public void name(){
final int value = 9;
int o;
if(value > 9) o = 5;
if(value <= 9) o = 8;
System.out.println(o);
}
Upvotes: 5
Reputation: 13465
During the compilation:
The compiler sees that you haven't initialized the variable 'o' and you are printing in the sysout.
you can achieve this :
public void name(){
int value = 9;
int o;
if(value > 9)
o = 5;
else
o = 8;
System.out.println(o);
}
Upvotes: 0