Is 'error: variable a might not have been initialized' really necessary in this if construct?

rahs :

How do I tell Java that I don't need to initialize a to have a working program and to not give me an error?

int a;
boolean b = true;
while (true) {
   if (b == false) {
       System.out.print(a);
       break;
   } else {
       b = false;
       a = 5;
   }
}

And if I can't, is there a reason why this is the way the compiler was designed?

Was it easy to design such a compiler or is this a mechanism to ensure that I restructure my code?

This is not the same question as this one

Stephen C :

Is 'error: variable a might not have been initialized' really necessary in this if construct?

Yes it is necessary. The Java language specification requires it. This is covered in JLS 16 - Definite Assignment.

"Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs."


How do I tell Java that I don't need to initialize a to have a working program and to not give me an error?

You can't tell Java that. You need to initialize the variable ... or restructure the code.


And if I can't, is there a reason why this is the way the compiler was designed?

Because the Java compiler must implement the specification, otherwise it is not a proper Java compiler. The specification says that is an error.

The real question is why the specification says that. The answer is so that compiler writers are not forced to included difficult theorem proving code in all Java compilers.

  • In the example you give, it is obvious to a programmer that the variable will always be initialized. However, a compiler needs to verify it. It needs to be absolutely sure, since an uninitialized variable would have undefined behavior.

  • Automated (undirected) verification is a complicated task. Complicated means more (compiler) code to write, more (compiler) bugs, etcetera.

  • The "state of the art" in this technology is not up to doing this kind of analysis for complicated Java code.

  • There are (theoretical) cases where verification that a variable is initialized is mathematically impossible.

So ... wisely ... the people who specified the Java language pushed this back to the programmer. You need to write your code so that variables are definitely assigned before use, according to the rules set out in the JLS.

And there is a second reason too. Suppose that the JLS did allow a Java compiler to accept

   System.out.print(a);

if and only if it could satisfy itself that a was (always) previously initialized. Now consider two Java compilers written by different people (or the same people at different times) to implement the same version of the JLS.

  • Compiler C1 can figure out that a is always initialized, and says that the program is valid.

  • Compiler C2 cannot figure out that a is always initialized, and says that the program is invalid.

We now have two Java compilers that ostensibly implement the same version of the JLS, but disagree on whether your example program (above) is valid. That is simply untenable.


To complicate things further, I suspect that something similar to the "definite assignment" checking must also occur when the JVM verifies bytecodes that have just been loaded. Thus a change to the JLS definite assignment rules would ripple on to the JVMS, and potentially affect the behavior of the JVM platform for other programming languages and tools that compile / generate directly to JVM bytecodes.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=111598&siteId=1