Hah, funny! Just a few days ago, I stumbled across this.
From the Java Language Specification, Third Edition, Section 8.9:
It is a compile-time error to reference a static field of an enum type that is not a compile-time constant (§15.28) from constructors, instance initializer blocks, or instance variable initializer expressions of that type. It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to itself or to an enum constant of the same type that is declared to the right of e.
Discussion
Without this rule, apparently reasonable code would fail at run time due to the initialization circularity inherent in enum types. (A circularity exists in any class with a "self-typed" static field.) Here is an example of the sort of code that would fail:
enum Color {
RED, GREEN, BLUE;
static final Map<String,Color> colorMap =
new HashMap<String,Color>();
Color() {
colorMap.put(toString(), this);
}
}
Static initialization of this enum type would throw a NullPointerException because the static variable colorMap is uninitialized when the constructors for the enum constants run. The restriction above ensures that such code won't compile.
Note that the example can easily be refactored to work properly:
enum Color {
RED, GREEN, BLUE;
static final Map<String,Color> colorMap =
new HashMap<String,Color>();
static {
for (Color c : Color.values())
colorMap.put(c.toString(), c);
}
}
The refactored version is clearly correct, as static initialization occurs top to bottom.