Consider the following Java Enum
definition:
public enum JavaEnumBug {
VALUE() {
@Override
int value() {
return _id;
}
};
private int _id = 123;
abstract int value();
}
The Java compiler will complain about the reference to _id
in the implementation of value()
:
Cannot make a static reference to the non-static field _id
This error message is very strange. There is no static reference to the field. There are two ways to make this message go away. The first is to drop the private
modifier from the field _id
. The second is to change the reference in value()
from _id
to super._id
.
Apparently, Sun/Oracle is aware of this problem as it is listed on the Bug Parade as bug #7119746. That bug is marked as Closed, Not a Defect. The argument starts by observing _id
is not visible through the inheritence chain due to being private. This is readily confirmed by changing the reference to _id
to this._id
whereupon the error message becomes:
The field JavaEnumBug._id is not visible
The bug diagnosis then goes on to argue that even though the reference is visible through class containment, that reference is considered to be static "since [VALUE] is declared as static in [JavaEnumBug]". I find this claim to be unconvincing. VALUE
is indeed static, but it is a static reference to an honest-to-goodness subclass of JavaEnumBug
. The instance itself has a perfectly well-defined _id
field in the superclass, and that field is visible under the rules of enclosing scopes.
So why does super._id work? The reason is that despite all the previous complaining about _id
being private from subclasses, it turns out that Java has a back door for accessing private members in superclasses:
abstract class Base {
private int _id = 123;
}
class Sub extends Base {
int value() {
return super._id;
}
}
According to section 6.6.1 of the Java Language Specification, super._id
should not be visible in Base
. But it is -- another bug. A bug that is convenient for the original problem, however.