Java Reference
In-Depth Information
Luckily, you do not have to learn the gory details of definite assignment to write Java programs.
Usually the definite assignment rules don't get in the way. If you happen to write a program that
really can assign to a blank final more than once, the compiler will helpfully point this out to you.
Only rarely, as in this puzzle, will you write a program that is safe but does not satisfy the formal
requirements of the specification. The compiler will complain just as if you had written an unsafe
program, and you will have to modify your program to satisfy it.
The best way to solve this kind of problem is to turn the offending field from a blank final into an
ordinary final, replacing the static initializer block with a static field initializer. This is best done by
refactoring the code in the static block into a helper method:
public class UnwelcomeGuest {
public static final long GUEST_USER_ID = -1;
private static final long USER_ID = getUserIdOrGuest();
private static long getUserIdOrGuest() {
try {
return getUserIdFromEnvironment();
} catch (IdUnavailableException e) {
System.out.println("Logging in as guest");
return GUEST_USER_ID;
}
}
... // The rest of the program is unchanged
}
This version of the program is clearly correct and is more readable than the original because it adds
a descriptive name for the field value computation, where the original version had only an
anonymous static initializer block. With this change to the program, it works as expected.
In summary, most programmers do not need to learn the details of the definite assignment rules.
Usually the rules just do the right thing. If you must refactor a program to eliminate a
compilation error caused by the definite assignment rules, consider adding a new method.
Besides solving the definite assignment problem, it may offer an opportunity to make the program
more readable.
 
 
Search WWH ::




Custom Search