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
IDdoes 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::enumeratorDeclarationaround 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 ofJCNewClassnodes if you like, but it suffices to say, as its javadoc does, that it models:And as you know, a
newoperation with a class body creates an anonymous class.