Community
Participate
Working Groups
The following code doesn't compile even if the JLS says "class body is governed by the usual rule of anonymous classes". page 255, chapter 8.9.". public enum EnumInitBlock { max { { val=3; } @Override public String toString() { return Integer.toString(val); } }; { val=2; } private int val; public static void main(String[] args) { System.out.println(max); // 3 } } Rémi Forax PS: i've reported the same bug to Sun.
Could you please provide the reference in the Sun bug database?
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6332253 but the bug is currently not available Rémi Forax
I do not see any contradiction with the spec in our current behavior. Consider the following example with anonymous type, it is still invalid: class XY { static void foo() { new XY() { int field = val; }; } private int val; } Problem comes from the fact you made the #val field private. By doing so, it is no longer inherited, and rather needs to be accessed through the enclosing instance. Now, because the method is static, it cannot reach the enclosing instance, thus the error message you obtain. In the case of an enum, enum constants are implicitly static, thus yielding the same diagnosis. The enum testcase is essentially equivalent to the following code below. public class EnumInitBlock { final static EnumInitBlock max = new EnumInitBlock(){ { val=3; } }; private int val; }
Closing as invalid.
Added EnumTest#test124
Ok, i agree with your explaination with anonymous class. It's not fully logic for me because : - if the val is not private, the code works - all the code are in the same compilation unit. But if i have a bug to report, it's against the way anonymous class are describe by the JLS. I'm not agree with the error reported. If you prefix val by "this.", the compiler report the error as "The field EnumInitBlock.val is not visible" This error seems better for me.
The reason for confusion is that you inherit the field and may reach it through enclosing instance. However, by making it private you cannot inherited it anymore. The fact it is in same unit doesn't change it. Only enclosing accesses are emulated through synthetics; only as long as there is a way to reach the enclosing instance, which the static context prevents you from. When you explicitly states "this.val", then you indicate you want the inherited field (as opposed to enclosing), and thus you hit the visibility issue. I agree the message isn't optimal in original case, because it is unclear to end user there is some static context involved in there. Enum constants are only implicitly static.