Folks,
Hi. I joined this discussion kind of late, but I'd like to try to clear up a few things. The terminology for describing nested classes was not well-specified until the second edition of the JLS came out last year. Unfortunately, the waters were more than a bit murky prior to that. Gilad Bracha is the man who deserves the credit for tightening up the spec.
In Item 18 of my book ("Favor static member classes over nonstatic"), I describe the new terminology, and tell you when to use which kind of nested class. I'll briefly summarize a few of the more important points here.
A nested class is a class defined within another class. A non-nested class is known as a top-level class. (There is no such thing as a "top level-nested classes.") There are four kinds of nested classes: static member classes, nonstatic member classes, anonymous classes, and local classes.
Here are simple examples:
<code>
class A {
// static member class
static class B { ... };
// nonstatic member class
static class C { ... };
static void foo {
// anonymous class
D d = new D() { ... };
// local class
class E { ... }
}
}
</code>
All nested classes but the first kind (static member classes) are known as inner classes. Note that it is
not the case that inner classes always have
enclosing instances: anonymous classes and local classes have enclosing instances only if they occur in a non-static context. In the example above, D and E are inner classes but they do not have enclosing instances, as foo is a static method of A. Don't feel bad if you didn't know this: it wasn't codified until recently, and it contradicts prior common usage. Unfortunately, there is no single term describing a nested class that does have an enclosing instance.
To answer a few of your specific questions:
1) Why exactly CAN'T a NON-static inner class have Static members? What is the essential feature about these classes that prevent it from possessing variables that are accessed at the class level rather than the object level? This is largely a philosophical issue. The designers of the nested class facility felt that such fields belonged in an enclosing non-inner class.
2) Can Non-static inner classes access Static fields of the enclosing class? By non-static inner classes, I assume you mean inner classes with enclosing instances? At any rate, the answer is yes: all nested classes can access static fields of enclosing classes.
2) One book I was reading said that Anonymous inner classes can only be contained within a METHOD of an inner class. But if this is true then I conclude that ALL Anonymous inner classes are in fact officially NOT inner classes, but are "top level nested classes". Still with me? The book goes on to say that Anonymous inner classes can only exist in a method BECAUSE such a class is INSTANTIATED AND DECLARED on the same line. But this doesn't seem to be a compelling explanation to me. Why can't such a class can't be INSTANTIATED AND DECLARED outside of any method. What is wrong with the following code? I'm afraid that I don't follow this, but the book you were reading would appear to be in error. It is not uncommon for anonymous classes to occur outside of methods, in static field initializers:
<pre>
public class Foo {
public Comparator WEIRD_ORDER = new Comparator { ... };
...
}
</pre>
I hope this clears things up a bit. I know that it's a pretty dense
subject. I go into a lot more detail in Item 18 of my book.
------------------
Joshua Bloch
Author of
Effective Java [This message has been edited by Joshua Bloch (edited July 11, 2001).]