views:

440

answers:

3
class OuterClass {
 class InnerClass {
  static int i = 100; // compile error
  static void f() { } // compile error
 }
} 

Although it's not possible to access the static field with OuterClass.InnerClass.i, if I want to record something that should be static, e.g. the number of InnerClass objects created, it would be helpful to make that field static. So why does Java prohibit static fields/methods in inner classes?

EDIT: I know how to make the compiler happy with static nested class (or static inner class), but what I want to know is why java forbids static fields/methods inside inner classes (or ordinary inner class) from both the language design and implementation aspects, if someone knows more about it.

Thanks.

+11  A: 

InnerClass cannot have static members because it belongs to an instance (of OuterClass). If you declare InnerClass as static to detach it from the instance, your code will compile.

class OuterClass {
    static class InnerClass {
        static int i = 100; // no compile error
        static void f() { } // no compile error
    }
}

BTW: You'll still be able to create instances of InnerClass. static in this context allows that to happen without an enclosing instance of OuterClass.

Asaph
hehe, 'no compile error'
Fortega
@Fortega: Just trying to keep things consistent with the OP's example.
Asaph
It is fine that static members are not allowed inside the inner class since they need an instance of outer class, but why is it that a non static inner class can contain a constant field that is static. i.e the below code is valid : class Outer { class Inner { static final int i =100;}}. Any thoughts ? Thx. sateesh
sateesh
@sateesh > `static final int i = 100;` is a compile time constant and is allowed. only `final` makes it possible :)
Gregory Pakosz
`InnerClass` does *not* belong to `OuterClass`, *instances* of it do. The two classes themselves have no such relationship. The question of why you can't have static methods in `InnerClass` still stands.
skaffman
+5  A: 

The idea behind inner classes is to operate in the context of the enclosing instance. Somehow, allowing static variables and methods contradicts this motivation?

8.1.2 Inner Classes and Enclosing Instances

An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).

Gregory Pakosz
maybe it's just **decided** like that
Gregory Pakosz
i think there should be some tradeoff :)
Jichao
life is full of compromises :)
Gregory Pakosz
you can't *instantiate* the non-static inner without a parent reference, but you can still *initialize* it.
skaffman
skaffman indeed
Gregory Pakosz
+3  A: 

I want to know is why java forbid static filed/method inside inner class

Because those inner classes are "instance" inner classes. That is, they are like an instance attribute of the enclosing object.

Since they're "instance" classes, it doesn't make any sense to allow static features, for static in meant to work without an instance in first place.

Is like you try to create an static/instance attribute at the same time.

Take the following example:

 class Employee {
     public String name;
 }

If you create two instances of employee:

Employee a = new Employee(); 
a.name = "Oscar";

Employee b = new Employee();
b.name = "jcyang";

It is clear why each one has its own value for the property name right?

The same happens with the inner class, each inner class instance is independent of other inner class instance.

So if you attempt to create a counter class attribute, there is no way to share that value across two different instances.

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

When you create the instance a and b in the example above, what would be a correct value for the static variable count? It is not possible to determine it, because the existence of the InnerData class depends completely on each of the enclosing objects.

That's why, when the class is declared as static, it doesn't needs anymore an living instance, to live it self. Now that there is no dependency, you may freely declare an static attribute.

I think this sounds reiterative but if you think about the differences between instace vs. class attributes it will make sense.

OscarRyz
I'll buy your explanation for static *properties* of the inner class, but as @skaffman points out in a comment to my answer, what about static *methods*? It seems as though methods should be allowed without mandating that they be detached from any instance. Indeed, in java, you can call static methods on instances (although it's considered bad style). BTW: I asked a colleague to attempt to compile the OP's code as C# and it *does* compile. So C# apparently allows this which demonstrates that what the OP wants to do doesn't violate some fundamental OO principle.
Asaph
Happens exactly the same with the methods. The point here is not the *attributes* or the *methods* being statis or not, but the fact the inner class it self being **instance** "stuff". I mean, the problem here is that an instance of such inner class doesn't exists until the outer class is created. Hence what method would be dispatched then if there is nothing. You would hit air only because you'll need an instance in first place.
OscarRyz
About C# ... well. It is not OO valid just because C# allows it, I don't mean it is wrong, but C# includes several paradigms to make the development easier even at cost of consistency ( you have to learn new things with each .NET release ) and it allows this and other kinds of things among others. I think that's a good thing. If the community feel an extra feature is cool enough C# may have it in the future.
OscarRyz