Why can't a top level class be static in Java?

41,901

Solution 1

All top-level classes are, by definition, static.

What the static boils down to is that an instance of the class can stand on its own. Or, the other way around: a non-static inner class (= instance inner class) cannot exist without an instance of the outer class. Since a top-level class does not have an outer class, it can't be anything but static.

Because all top-level classes are static, having the static keyword in a top-level class definition is pointless.

Some code to play around with:

public class Foo {

    public class Bar {
         // Non-static innner class
    }

    public static class Baz {
         // Static inner class
    }
}

public class Example {
    public static void main(String[] args) {
        new Foo(); // this is ok
        new Foo.Baz(); // this is ok
        new Foo.Bar(); // does not compile!

        Foo f = new Foo();
        Foo.Bar bar = f.new Bar(); //this works, but don't do this
    }
}

I put the "but don't do this" in there because it's really ugly code design. Instance inner classes should not be visible outside the outer class. They should only be used from within the outer class.

Solution 2

Simply put, a top-level type declaration cannot be static, because the Java Language Specification (JLS) doesn't say that it can be. The JLS says this explicitly about the static keyword as a modifier of top-level classes:

The modifier static pertains only to member classes (§8.5.1), not to top level or local or anonymous classes.

However, the accepted answer - which has many upvotes - says that this is because top-level classes are implicitly static "by definition", so the static modifier would be unnecessary. That is wrong.

The word "static" appears in the JLS in quite a few places, but never to refer to top-level type declarations. Here is an exhaustive list of things that can be "static":

There are no uses of the word "static" in the JLS to refer to top-level type declarations; so as well as not being explicitly static, they are not (and cannot be) "implicitly" static, by definition.

Solution 3

static can be added nested classes of an interface, even though this is the default.

I believe static cannot be added to top level classes because initially there were no nested classes and you couldn't add static to any class.

Later nested class were added and static could be added to nested classes, however there is a tendency not to change the syntax any more than needed so it wasn't added to top level classes. (as there was no need/benefit)

Share:
41,901
ngesh
Author by

ngesh

Updated on July 09, 2022

Comments

  • ngesh
    ngesh almost 2 years

    Can't find a satisfactory answer anywhere.

  • ngesh
    ngesh over 12 years
    @barend.. they why compiler complains when i add static keyword
  • hari krishnan
    hari krishnan over 12 years
    The keyword has no value, so they left it out. I think this is a design choice about readability. You have the same thing with the public keyword when you define a method on an interface (it's just as pointless), but in that case they left it in.
  • Vishy
    Vishy over 12 years
    +1: nested enum are effectively static and final but you can't use either.
  • iOS Padawan
    iOS Padawan over 10 years
    @Peter You can use static in fact.
  • Jaxox
    Jaxox over 9 years
    @Barend can you actually prove that or provide some ref about "All top-level classes are, by definition, static."? I am trying to search online but couldnt' find anything about it. for the interface is implicit public so you can either declare it or not and that doesn't change anything, at least the compiler doesn't complain but for top level class you can't declare static which mean it is not implicitly static! so what make you think they are? thanks.
  • hari krishnan
    hari krishnan over 9 years
    @Jaxox I have no refs to give you. What makes me think the above is summarized in the second paragraph. Without an outer class to give object scope/context, a top level class can only ever live in the static (or "global" or whatever you want to call it) scope/context.
  • Talha
    Talha almost 6 years
    This is quite unsatisfying answer since, (a) no official docs/ source code reference. (b) if static is pointless then adding it shouldn't be a problem like adding public in interface signatures.
  • VimNing
    VimNing about 5 years
    Maybe you could elaborate more on your answer, I think it will be better than the accepted one (I've upvoted).
  • ShakibaZar
    ShakibaZar almost 5 years
    @Barend if it is as you say and top-level classes are static, can we say that top-level class save in stack area like static fields and methods?
  • kaya3
    kaya3 about 4 years
    "By definition" is wrong; the JLS does not give any overall definition of what the word "static" means, and the only things described as being static in the JLS are static fields, static methods, static member type declarations and static initializers. The only top-level declarations described using the word "static" are single-static-import declarations and static-import-on-demand declarations, but in those cases "static" refers to the names imported, not the import declarations themselves. So there is no definition in the JLS which says or implies what you claim is "by definition".
  • Scratte
    Scratte about 4 years
    I don't think the default applies for Java 11. I'm getting a error: modifier default not allowed here for public default class StackOverflowTest {...} Could you specify the Java version where this is allowed?
  • Holger
    Holger about 4 years
    Being “pointless” is not a valid explanation. A nested interface or enum type is truly always static, still, nothing forbids you to add the redundant “pointless” static modifier.