inner class scope issues
Hi all,
[SSCCE at end of post]
I don't understand the scope of attributes & methods for an inner
static class. Although I learnt a lot doing the research to write this
message! :-)
I'll describe not only what I don't understand, but also what I came
to understand, so it may be of help to others.
I came upon this while defining a different behavior for each instance
of an enum, using methods and attributes from the enum class. I
encountered strange error messages from the compiler.
I reduced the problem to an SSCCE, distinguishing access to private &
protected, and static & non-static, methods of the enum (see SSCCE).
After that I reproduced the SSCCE replacing the enum with a class with
"public static final" attributes. Finally, I reproduced again the
SSCCE without any anonymous class, using an inner class. To my great
satisfaction, I obtained the same results! :-)
In that way I eliminated one misinderstanding that I had: I had
overlooked the fact that enums with specialized behavior are
implicitely static anonymous classes. This explained the static access
issues, as well as explaining why I had problems accessing private
stuff: I was in an anonymous sub-class, not in the enum class itself.
A google search has shown my problem is more or less described here:
http://stackoverflow.com/questions/581450/static-context-in-enum-definition
(in particular, in mentions the error messages that bothered me
initially)
BTW, I've also read this
http://java.sun.com/docs/books/jls/third_edition/html/classes.html
I'm providing several SSCCEs. One is with enum, the other is the same
without enums, the last one illustrates the same with only a static
inner class.
There remains one question though:
How come I can access a private method of the super-class using
super.method instead of this.method?
I would have thought I shouldn't be able to access it at all...
For those who wonder (I know this NG!), this is the usage I'm after:
I'm defining a simple command-line interface. The commands are
provided as an enum, which has an abstract "execute" method,
implemented (in an anonymous way) by each instance. Of course, some
commands are simple, but others require help from other classes, and
that's where I started having problems.
The advantage is that I can use all enum utilities, and also that
adding a new command is one step (no switch to modify).
Here's an idea of the code:
public enum MyCommand {
doSomething {
public void execute() {
// ... do something
}
},
doOtherwise {
public void execute() {
// ... do otherwise
}
};
public abstract void execute();
}
Does anyone else use enumerates with behavior to implement command-
line interfaces?
Most examples I've seen use enums for command-line instructions... but
still do a switch. This seems like a shame, when it's possible to
directly code the behavior into the enum!
(in general I tend to regard switching as an bad thing, because it can
be replaced with specialized behavior, aka overriding)
SSCCE (3 of 'em!):
===================================
package enumTests;
/**
* compiler error:
* "The method somePrivateMethod() from the type MyPeople is not
* visible"
*
* previous compile error (for attribute):
* "Cannot make a static reference to the non-static field
* somePrivateAttribute"
* previous compile error (for method):
* "Cannot make a static reference to the non-static method
* somePrivateMethod() from the type EnumTests"
*/
public enum MyPeople {
bob {
private void bobsJob() {
somePrivateStaticMethod();
this.somePrivateMethod(); // compile error
super.somePrivateMethod(); // works fine!
this.someProtectedMethod();
}
};
private void somePrivateMethod() {}
static private void somePrivateStaticMethod() {}
protected void someProtectedMethod() {}
}
===================================
package enumTests;
public class NotAnEnum {
public static final NotAnEnum bob = new NotAnEnum() {
private void bobsJob() {
somePrivateStaticMethod();
this.somePrivateMethod(); // compile error
super.somePrivateMethod(); // works fine!
this.someProtectedMethod();
}
};
private void somePrivateMethod() {}
static private void somePrivateStaticMethod() {}
protected void someProtectedMethod() {}
}
===================================
package enumTests;
public class SomeSuperClass {
public static class SomeInnerClass extends SomeSuperClass {
private void someInnerMethod() {
somePrivateStaticMethod();
this.somePrivateMethod(); // compile error
super.somePrivateMethod(); // works fine!
this.someProtectedMethod();
}
}
private void somePrivateMethod() {}
static private void somePrivateStaticMethod() {}
protected void someProtectedMethod() {}
}