Alex Rivera | Logout

Why can't we have static method in a (non-static) inner class (pre-Java 16)?

Asked 2009-06-10T11:52:05.233
153

Why can't we have static method in a non-static inner class?

public class Foo {
    class Bar {
        static void method() {} // Compiler error
    }
}

If I make the inner class static it works. Why?

public class Foo {
    static class Bar { // now static
        static void method() {}
    }
}

In Java 16+, both of these are valid.

Edit
Report

3 Answers

50

There's not much point to allowing a static method in a non-static inner class; how would you access it? You cannot access (at least initially) a non-static inner class instance without going through an outer class instance. There is no purely static way to create a non-static inner class.

For an outer class Outer, you can access a static method test() like this:

Outer.test();

For a static inner class Inner, you can access its static method innerTest() like this:

Outer.Inner.innerTest();

However, if Inner is not static, there is now no purely static way to reference the method innertest. Non-static inner classes are tied to a specific instance of their outer class. A function is different from a constant, in that a reference to Outer.Inner.CONSTANT is guaranteed to be unambiguous in a way that a function call Outer.Inner.staticFunction(); is not. Let's say you have Inner.staticFunction() that calls getState(), which is defined in Outer. If you try to invoke that static function, you now have an ambiguous reference to the Inner class. That is, on which instance of the inner class do you invoke the static function? It matters. See, there is no truly static way to reference that static method, due to the implicit reference to the outer object.

Paul Bellora is correct that the language designers could have allowed this. They would then have to carefully disallow any access to the implicit reference to the outer class in static methods of the non-static inner class. At this point, what is the value to this being an inner class if you cannot reference the outer class, except statically? And if static access is fine, then why not declare the whole inner class static? If you simply make the inner class itself static, then you have no i

answered 2009-06-10T13:22:59.887
3

Short answer: The mental model most programmers have of how scope works is not the model used by javac. Matching the more intuitive model would have required a big change to how javac works.

The main reason that static members in inner classes are desirable is for code cleanliness - a static member used only by an inner class ought to live inside it, rather than having to be placed in the outer class. Consider:

class Outer {
   int outID;

   class Inner {
      static int nextID;
      int id = nextID++;

      String getID() {
         return outID + ":" + id;
      }
   }
}

Consider what is going on in getID() when I use the unqualified identifier "outID". The scope in which this identifier appears looks something like:

Outer -> Inner -> getID()

Here, again because this is just how javac works, the "Outer" level of the scope includes both static and instance members of Outer. This is confusing because we are usually told to think of the static part of a class as another level of the scope:

Outer static -> Outer instance -> instanceMethod()
         \----> staticMethod()

In this way of thinking about it, of course staticMethod() can only see static members of Outer. But if that were how javac works, then referencing an instance variable in a static method would result in a "name cannot be resolved" error. What really happens is that the name is found in scope, but then an extra level of check kicks in and figures out that the name was declared in an instance context and is being referenced from a static context.

OK, how does this relate to inner classes? Naively, we think there is no reason inner classes can't have a static scope, because we are picturing the scope working like this:

Outer static -> Outer instance -> Inner instance -> getID()
         \------ Inner static ------^

In other

answered 2012-01-04T22:27:44.843
-3

You are allowed static methods on static nested classes. For example

public class Outer {

  public static class Inner {

    public static void method() {

    }
  }
}
answered 2009-06-10T12:14:18.543

Your Answer