Community
Participate
Working Groups
Enum constants with class bodies generate a synthetic constructor access warning when using the default constructor. In the following class, the opening brace of each enum constant class body is flagged with this warning: "Access to enclosing constructor Direction() is emulated by a synthetic accessor method. Increasing its visibility will improve your performance" Perhaps the warning is accurate, but it seems like it should be suppressed in this case, since the constructor is implicit. Also, any performance impact is negligible since enum constants are singletons. public enum Direction { INPUT { public Direction getReverse() { return OUTPUT; } }, OUTPUT { public Direction getReverse() { return INPUT; } }, INOUT { public Direction getReverse() { return INOUT; } }; public abstract Direction getReverse(); }
Created attachment 18781 [details] Apply on ProblemReporter in HEAD I propose the following patch. We simply need not to report the warning, but we still need the synthetic method.
I am rather questionning whether the default constructor should be public to match the type. If the emulation is real, then the warning is sound.
Perhaps my argument is with the JLS. From the JLS 3 draft: "If the enum type has no constructor declarations, a parameterless default constructor is provided (which matches the implicit empty argument list). This default constructor is private." In no other case is use of an implicit constructor cause for a performance warning. It seems like the compiler should promote the implicit constructor to default access if any enum constants have bodies, analogous to this JLS rule: "An enum type is implicitly final unless it contains at least one enum constant that has a class body." I don't know whether you feel you have the discretion to do this promotion (since javac probably doesn't), or feel it wise to (optionally?) suppress the warning, but I just wanted to make you aware of it, since it seems odd to get a warning for something implicit.
Oh, I see what you mean now. Need to think about it. It is indeed true that the current behavior is mandated by the spec, and maybe a situation where we need to customize our warning support.
The warning intent is to signal a performance issue user may not realize. However it suggests to change the visibility, which isn't an option here due to enum spec. Loosing the warning altogether in this situation is a bit annoying, as the emulation would occur silently (which is against the purpose of this diagnostic).
Actually, I just realized that when adding a constructor, with default access modifiers, then the warning goes away. We incorrectly forget to consider the constructor has private by default.
Fixed private modifier by default, and silenced offending warning. Added EnumTest#test083-084. Fixed
Verified in I20050330-0500