Why does the Java compiler not understand this variable is always initialized?

class Foo{ public static void main(String args[]){ final int x=101; int y; if(x>100){ y=-1; } System.out.println(y); } } 

The Java compiler understands that the condition of the if statement is always true, and therefore, y will always be initialized. Compilation error, as expected.

 class Bar{ public static void main(String args[]){ final int x; x=101; int y; if(x>100){ y=-1; } System.out.println(y); } } 

But when I break the declaration and initialization of x on two lines, the compiler does not seem that the condition is always true, and y will always be initialized.

 final int x; x=101; byte b; b=x; System.out.println(b); 

The same thing happens here, and the compiler gives a loss of error accuracy.

 final int x=101; byte b; b=x; System.out.println(b); 

Again, the compiler can understand that x is inside range b.

+52
java initialization conditional final
Nov 05
source share
3 answers

This is due to how the compiler determines whether the statement will execute or not. It is defined in JLS # 16 :

Each local variable and each empty final field must have a specifically assigned value when any access to its value occurs.

In your case, the compiler cannot determine that y definitely assigned and gives you an error. This is due to the fact that he will need to determine that the condition is always true, and this is possible only if the condition in if is a constant expression.

JLS # 15.28 defines constant expressions:

A compile-time constant expression is an expression representing a primitive type or String value that does not end abruptly and is composed using only the following:

  • [...]
  • Simple names (ยง6.5.6.1) that refer to constant variables (ยง4.12.4).

JLS # 4.12.4 defines constant variables as:

A variable of a primitive or String type, which is final and initialized by the expression of a compile-time constant, is called a constant variable.

In your case, final int x = 101; is a constant variable, but final int x; x = 101; final int x; x = 101; is not.

+26
Nov 05 '12 at 15:57
source share

As part of the focus on portability, there is a very specific set of rules for the compiler that must accept and that it must reject. These rules allow and require only limited flow analysis when determining whether a variable is defined when using it.

See The Java Language Specification. Chapter 16. Defined Assignment

The critical rule is the value 16.2.7. if "Statements" , "if (e) S". The rule, in order to be specifically assigned, extends to:

V is assigned after if (e) S if and only if V is assigned after S and V is assigned after e when false.

y is the corresponding V. It is not assigned before the if statement. This is indeed assigned after S, y = {y = -1;}, but there is nothing that would be assigned when x> 100 is false.

Thus, y is not definitely assigned after the if statement.

A more complete flow analysis will determine that the condition x> 100 is always true, but the compiler requires JLS to reject the program based on these specific rules.

The final variable is beautiful. The rule is actually: -

"This is a compile-time error if the final variable is assigned the value if it is definitely not assigned (ยง16) immediately before the assignment."

The declaration leaves it clearly unassigned, and even limited flow analysis can determine that x is still definitely not assigned at assignment.

+45
Nov 05 '12 at 15:56
source share

What you did for the variable x in the second code is called the blank final variable. If the final variable is not initialized when it is declared, it is called the empty final variable.

Many Java developers believe that the value of the final variable is known at compile time. This is not always true. It is said that the value of an empty final variable is NOT known at compile time. Therefore, your second code will give you a compilation error. The compiler can see that you initialized the final variable x , but the compilation does not know its value. Therefore, the compiler cannot resolve the if statement. Therefore, he believes that the variable y not initialized.

You can learn more about Java final variables here .

+11
Nov 05 '12 at 16:13
source share



All Articles