Stupid top-level nested classes, stupid Java.


If you’ve dabbled in Java maybe you’ve come across the term top level nested class or the similar term top level inner class. The terms are stupid and wrong and should not be tolerated (so let’s hope you haven’t come across them). It’s Java programmers being imprecise. We don’t need people being imprecise when they talk about computer programming languages; usually the hardest thing about learning a new language is the terminology, don’t make it harder by abusing it.

Not only does top level nested class not make common sense—how can a class be both top level and nested?—the Java language specification (the JLS, 2nd edition) has this to say in Chapter 8:

A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.

So the specification backs up what common sense tells us. A top level class cannot be a nested class.

What people usually mean when they say top level nested class is a static member nested class. I think. It’s hard to say what they mean when they talk about things with no definition.

You might also have come across the term static inner class. That’s a nonsense term also. JLS 2nd edition section 8.1.2 says, “An inner class is a nested class that is not explicitly or implicitly declared static”. So you clearly can’t have a static innner class.

To be fair on the Java community, the exact situation is a little bit tricky; I drew several versions of this diagram (as a Venn diagram and a class heterarchy before settling on the Karnaugh map style version here), and it was factually incorrect on earlier versions.

A smaller version of the PDF.

The rub is that the most often referred to box, the non-static member class (marked with an x), doesn’t have a cute catchy title, which is why people abuse the inner class terminology. Naming is important, and I think Sun got it wrong.

The diagram took quite a bit of digging. Note that “all local classes are inner classes” (from JLS 2nd edition section 14.3), and “an anonymous class is always an inner class” (from JLS 2nd edition section 15.9.5). But note that both local classes and anonymous classes can appear in static methods, so they might not have any enclosing instances anyway.

If you want to see some real inner classes (including the rarely used feature of extending an inner class in an unrelated class), then check out my java.awt.Paint article.

There is one thing that niggles me, because I never found out: How can a nested class be declared implicitly static?

9 Responses to “Stupid top-level nested classes, stupid Java.”

  1. “How can a nested class be declared implicitly static?”

    Classes inside interfaces are implicitly static.

  2. nicerobot Says:

    I think you’re experiencing ambiguities with and between spoken language and programming language terminology.

    It seems reasonable to me that a top-level nested class can exist and make sense in a few circumstances, if, for example, it is the root of a nested-class class hierarchy, especially if it’s static. For example, consider C as a container for static, nested classes X, Y, and Z with Z as the root, base class of X and Y, C.Y -> C.Z, C.X -> C.Z. Z can be called a top-level (or base/root), nested class. Also, C.X and C.Y, although nested in terms of their declaration, are effectively top-level when used because C can be thought of as an organizational mechanism, forced namespace, as a type of packaging.

    public abstract class C {
    private C() {}
    private static class Z {}
    public static class X extends Z {}
    public static class Y extends Z {}

  3. drj11 Says:

    nicerobot: Yes, I think you’re right, I am experiencing that ambiguity and it’s exactly what I’m complaining about.

    Programming is a precise business and it uses precise language. Inevitably terms are borrowed from natural language. For example, most programming languages use the word operator in ways that would confuse people not skilled in the arts.

    It’s important to maintain this precision in order to clearly communicate. The JLS already defines the terms top-level class and nested class. We should not muddy the waters by using those terms when we mean something else. Yes, I agree that both top-level and nested have reasonable natural language meanings, but in the Java world I’m already sensitised to their Java meanings. Just as I am with words like operator, expression, object. So when I see those words the technical precise meaning is triggered.

    Java has only one root class and it is Object. In Objective C you can declare as many root classes as you like, but not Java.

  4. nicerobot Says:

    Well, we disagree. I don’t think we need a distinct natural language term for every possible structural incarnation of the programming language. Overloading and abstraction of the natural language terminology is useful to keep the language specification succinct.

    As I think I’ve shown, there is a valid use for the term “top level” when applied to nested classes even though it appears to “violate” the strict application of those terms as defined by the spec you reference but does not appear to violate another, less ambiguous, definition. It seems to me, according to the latter definition, C.X and C.Y are both top level _and_ nested.

  5. drj11 Says:

    I have no problem with the language of the specification (the JLS in this case). Like I say I’m already used to giving perfectly ordinary words (like object) a precise technical meaning in the context of programming.

    I have a problem with people taking this perfectly reasonable technical language and using it for something else.

    “A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.” How is that ambiguous? In particular, the second sentence? How can I have a top-level nested class?

    Sure, you’re free to communicate in whatever language you like, but when you say “top-level” you obviously don’t mean the same thing that the JLS means by “top-level”. So, what do you mean? I have no idea, and that’s the problem.

    The other section of the JLS that you reference, section 7.6, simply says that a top-level type is either a top level class or a top level interface, that’s all. Sure, it also says you can declare a type public so that it is accessible outside its package, but that doesn’t mean any type that is accessible from another package is a top level type. If you believe that, how do you square it with “The scope of a top level type is all type declarations in the package in which the top level type is declared.” which is also in section 7.6?

    In other words a type X is a top level type if I can import the package containing X and then refer to X using its simple name alone, with no dots.

    I would call your C.X what it is. A public static nested class.

  6. nip Says:

    I agree with drj11. Cos we should not use meaningless words because those words are convenient for us. Else there is no point of having a JLS.


  7. sam Says:

    i need a java program for matrix multiplication using two classes

  8. drj11 Says:

    @sam: Noted.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: