Hah, funny! Всего несколько дней назад я наткнулся на это.
Из спецификации языка Java, Третье издание, Раздел 8.9:
Это ошибка времени компиляции для ссылки на статическое поле типа перечислений, который не является константой времени компиляции (§15.28) от конструкторов, блоков инициализатора экземпляра или выражений инициализатора экземпляра этого типа. Это ошибка времени компиляции для конструкторов, блоков инициализатора экземпляра или выражений инициализатора экземпляра константы enum e для ссылки на себя или на константу перечисления того же типа, которая объявляется справа от e.
Обсуждение
Без этого правила, по-видимому, разумно код потерпит неудачу во время выполнения из-за инициализацию округлость, присущие типов перечислений. (А округлость существует в любом классе с «самостоятельной напечатал» статического поля.) Вот пример подобного кода, который будет терпеть неудачу:
enum Color {
RED, GREEN, BLUE;
static final Map<String,Color> colorMap =
new HashMap<String,Color>();
Color() {
colorMap.put(toString(), this);
}
}
Статическая инициализация этого перечислимого типа будет бросать NullPointerException, потому что статическая переменная colorMap не инициализируется, когда выполняются конструкторы для констант перечисления. Ограничение выше гарантирует, что такой код не будет компилироваться.
Обратите внимание, что пример может быть легко переработан, чтобы работать должным образом:
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);
}
}
переработан версия явно правильно, так как статическая инициализация происходит сверху вниз.
Возможно, стоит указать, является ли «ключ» для карты всегда «именем» перечисления. Если это так, это имеет большое значение в том, как вы это сделаете. – DJClayworth 2010-11-25 16:53:05