Question:
Why can't I have a static member in an inner class?
Answer:
The simple answer is that static member variables and methods are
disallowed by the Inner Classes Specification that was introduced with
Java 1.1. But that alone will not satisfy most people looking for an
answer to this question. You want to know why this is disallowed by
the specification. Before moving on to that, I should distinguish
between an inner class and a static inner class. An inner class is a
class declared within the scope of another class, either local to a
class declaration (i.e., as a class member), a block of statements, or
an expression (in which case it is an anonymous class). However, it is
possible to define a static inner class within a top-level class
declaration. A class defined in this way is itself treated as a
top-level class, meaning that it can only access its own members and
static members of its enclosing class. But since it is declared
within the scope of another class, it cannot be referenced
outside of the enclosing class without specifying a qualified name
(e.g., OuterClassName.InnerClassName).
Inner classes cannot have static members because static members are
top-level lexical entities. In other words, static members are
accessible outside of a given class's scope. Inner classes themselves
are not top-level entities, being bound to specific instances of their
enclosing class. If you feel you really must have an inner class to have static
member, just define that variable as a member of the enclosing class.
But it so happens that static inner class can have static members.
This is because they are top-level classes, and as such are not bound
to specific instances of their enclosing class.
The best way to think about all of this is to consider inner classes
and static inner classes as two different animals by introducing the
term nested class, which is loosely used in the Inner Classes
Specification. Think of both types of classes as nested classes, and
only use the term inner class to refer to non-static nested classes.
Therefore a static nested class is not really an inner class, and can
have static members. The following example differentiates the
behavior of inner classes and static nested classes with respect to
static members:
public class InnerClassExample {
private String __privateMember = "__privateMember";
private static String __staticPrivateMember = "__staticPrivateMember";
// This is an inner class, it cannot have static members.
public class InnerClass1 {
public void print() {
System.out.println(__privateMember);
System.out.println(InnerClass2.__staticInnerClass2Member);
}
}
// This is a static nested class, which makes it a top-level class,
// allowing it to have static members.
public static class InnerClass2 {
public static String __staticInnerClass2Member =
"__staticInnerClass2Member";
public void print() {
// Accessing __privateMember would be a compile-time error.
// InnerClass2 is a top-level class and can only reference its
// own member variables and the static variables of its lexically
// encompassing class, InnerClassExample.
System.out.println(__staticPrivateMember);
System.out.println(__staticInnerClass2Member);
}
}
public void testInnerClasses() {
InnerClass1 class1 = new InnerClass1();
InnerClass2 class2 = new InnerClass2();
class1.print();
class2.print();
}
public static final void main(String[] args) {
InnerClassExample example = new InnerClassExample();
example.testInnerClasses();
}
}