Я хотел создать 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
...)