Я хотел создать enum, где каждая константа имеет связанный с ней Map. Я выполнил это, указав каждой константе инициализатор экземпляра, например:
import java.util.HashMap;
import java.util.Map;
public enum Derp {
FOO {{
mMap.put("bar", 1);
}};
// cannot be private
protected final Map<String, Integer> mMap = new HashMap<>();
}
Я обнаружил, что если mMap есть private, на него нельзя ссылаться в инициализаторе экземпляра. Ошибка Cannot make a static reference to the non-static field mMap. Прежде чем причина для этого возникла, я посоветовался с JLS §8.9.2, в котором говорится, в частности:
Это ошибка времени компиляции для конструкторов, блоков инициализатора экземпляра или выражений инициализатора экземпляра константы перечисления
eдля ссылки наeили на константу перечисления того же типа, которая объявлена в справа отe.
Разве я не нарушаю это правило, неявно ссылаясь на FOO в FOO собственный экземпляр экземпляра? Как это компилируется? Он не только компилируется, но работает корректно во время выполнения.
(Мне пришло в голову, что mMap не может быть private, потому что я неявно создаю анонимный подкласс, который не может ссылаться на поле private в своем суперклассе. Это немного странно, поскольку перечисления неявно final...)