Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Enum private methods: did everyone know this but me?

843793Jul 2 2005 — edited Jul 7 2005
Consider the following code:
class C {
    final C C1 = new C() {
        public void f() {
            g();
        }
    };
    private void g() {
    }
}

enum E {
    E1 {
        public void f() {
            g();
        }
    };
    private void g() {
    }
}
It struck me that the class and the enum are structurally very similar: the class has an inner class that references a private method; the enum has a value that references a private method.

But the big difference is: the enum won't compile. Unless I change the protection on g() to "protected" or less, it throws an error.

And the bizarre part is, the error is not "g has private access" or "cannot find symbol". No, it's "non-static method g() cannot be referenced from a static context"! WTF?

I solved the mystery by utter accident, when I changed the class to
class C {
    static final C C1 = new C() {
        ...
That is, I made the variable referring to the instance of the inner class static. That made the class fail to compile with the same "static context" error I saw in the enum.

It took several minutes of open-mouth staring at the screen to get it: in the original class, the g() being called was not in the same object, but in the outer object. Methods of object declared in a derived class cannot get to private members, even of the same object, declared in an ancestor class: that is the meaning of the word "private". But methods of an inner class can get to private members of the outer class. So in the original class, the inner-object could not see its own g(), so it looked at the outer-object's g(); when I changed the inner-object to static, there was no outer object, and I got an error to that effect.

Enum values are basically solitary instances of static inner classes of the class representing the enum itself and so, in the same situation produce the same error message.

Oddly, the following does compile:
enum E {
    E1 {
        public void f() {
            E1.g();
        }
    };
    private void g() {
    }
}
That is, instead of accessing g() as E.this.g(), I accessed it statically as E.E1.g(). In fact, this was the first thing I tried -- under the wrong impression that f() was static within E1, not the E1 was static within E. In retrospect, I can see why it works, but I cannot explain it properly or defend it intellectually.

Who sez Java ain't fun?

M.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 4 2005
Added on Jul 2 2005
8 comments
469 views