I wanted to create an enum
where each constant has a Map
associated with it. I accomplished this by giving each constant an instance initializer, like so:
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<>();
}
I found that if mMap
is private
, it cannot be referenced in the instance initializer. The error is Cannot make a static reference to the non-static field mMap
. Before the reason for this occurred to me, I consulted JLS §8.9.2, which says in part:
It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant
e
to refer toe
or to an enum constant of the same type that is declared to the right ofe
.
Aren't I breaking this rule by implicitly referencing FOO
in FOO
's own instance intializer? How does this compile? It not only compiles, but works correctly at runtime.
(It occurred to me that mMap
cannot be private
because I'm implicitly creating an anonymous subclass which cannot reference a private
field in its superclass. Which is a bit weird in itself since enums are implicitly final
...)