I would like someone to explain the compilation error this file causes:
public enum TestEnum {
A {
@Override
void someMethod() {
System.out.println("A: " + x);
}
},
B {
@Override
void someMethod() {
System.out.println("B: " + x);
}
};
private int x;
abstract void someMethod();
}
The compilation error is:
TestEnum.java:11: error: non-static variable x cannot be referenced from a static context
System.out.println("B: " + x);
If I remove the private
modifier, the class compiles without error. This seems to imply that someMethod
is a static context (is it?) and that removing the access modifier on int x
makes it a static variable (does it?). Why is this the case?
Environment:
- java version "1.8.0_51"
p.s. I'm trying to initialize a Properties
field in the enum constructor, which delegates to an abstract init
method of each enum instance. That's where I'm running into the above error message. I don't want x/properties
to be a static field; it should be unique for each enum instance.
Duplicate counter-argument
How to use fields in java enum by overriding the method?
To start, if you don't mind an appeal to an authority, Jon Skeet commented on that question by saying "That's very odd - I'm surprised that the override counts as a static context. Note that making the field protected removes the error, which is also odd..."
As far as I can tell in Rafael's excellent answer, he never addresses this oddity. Yes, A
and B
are equivalent to static nested classes, but a static inner class is roughly equivalent to a normal top-level class: it does not mean that the all of the methods and fields of the class are static as well. Are the methods of enums in static context? So in Rafael's answer, the doIt
methods are actually static methods even though they are not marked as such?