Java Reference
In-Depth Information
}
}
class IdUnavailableException extends Exception {
IdUnavailableException() { }
}
Solution 38: The Unwelcome Guest
This program seems straightforward. The call to getUserIdFromEnvironment appears to throw an
exception, causing the program to assign the value of GUEST_USER_ID ( -1L ) to USER_ID and to print
Logging in as guest . Then the main method executes, causing the program to print User ID: -1 .
Once again, appearances are deceiving. The program doesn't compile. If you tried to compile it, you
saw an error message that looked something like this:
UnwelcomeGuest.java:10:
variable USER_ID might already have been assigned
USER_ID = GUEST_USER_ID;
^
What's the problem? The USER_ID field is a blank final , which is a final field whose declaration
lacks an initializer [JLS 4.12.4]. It is clear that the exception can be thrown in the try block only if
the assignment to USER_ID fails, so it is perfectly safe to assign to USER_ID in the catch block. Any
execution of the static initializer block will cause exactly one assignment to USER_ID , which is just
what is required for blank finals. Why doesn't the compiler know this?
Determining whether a program can perform more than one assignment to a blank final is a hard
problem. In fact, it's impossible. It is equivalent to the classic halting problem , which is known to
be unsolvable in general [Turing36] . To make it possible to write a Java compiler, the language
specification takes a conservative approach to this issue. A blank final field can be assigned only
at points in the program where it is definitely unassigned . The specification goes to great lengths
to provide a precise but conservative definition for this term [JLS 16]. Because it is conservative,
there are some provably safe programs that the compiler must reject. This puzzle illustrates one
such program.
 
 
Search WWH ::




Custom Search