Reproducer :
enum IDs {
ID {
@Override
void getId() {
w(); // warning here
}
};
void getId() {}
private static void w() {}
}
Warning emitted :
Access to enclosing method w() from the type IDs is emulated by a synthetic accessor method
I understand what synthetic methods are - what I do not get is how they come into play with enums - I would expect enum instances to have all private methods I define in the enum. Are instances really nested classes ?
An enum instance which defines methods, as your
ID
does here, is a singleton of an implicit anonymous subclass of the enum class. The normal access rules apply between the subclass and the enum class, so a synthetic accessor is required to see private features of the enum class.The Java Language Specification requires enums to work this way:
It's certainly how they're actually implemented. In the JDK's javac, this happens in
JavacParser::enumeratorDeclaration
around line 3344 (in this version):The relevant bits there are that if there is a left curly bracket (
LBRACE
) in the declaration, then a class body is parsed (classOrInterfaceBody(...)
) for an anonymous class (names.empty
), and this is then used as the class body in an instance creation expression (NewClass(..., body)
). You can follow through the compilation ofJCNewClass
nodes if you like, but it suffices to say, as its javadoc does, that it models:And as you know, a
new
operation with a class body creates an anonymous class.