Static Nested Classes

A static nested class is, not surprisingly, a nested class that is declared with the keyword static on the declaration. Many developers call these classes "inner classes" as well. However, these developers are wrong. To be an inner class, a class has to have instance scope. To understand how static nested classes function, see Example 6-8.

Example 6-8. A static nested class
package oracle.hcj.nested;
public class OuterClass {
 private static final String name = "Robert";
 private static String company = "Oracle";
 private int value = 5;
 public static class SomeClass {
 public void someMethod( ) {
 System.out.println(company);
 System.out.println(name);
 System.out.println(value); // <= Compiler error
 }
 }
}


This code declares a public static nested class. This nested class can access the various static members of the enclosing class. However, unlike inner classes, it cannot access any instance variables in the enclosing class. This is an important difference between static nested classes and inner classes. Formally, it can be said that an inner class is instance-scoped and a static nested class is class-scoped. The class scope of a static nested class makes it easier to use:

package oracle.hcj.nested;
public class StaticNestedClassDemo {
 public static void main(final String[] args) {
 OuterClass.SomeClass obj = new OuterClass.SomeClass( );
 obj.someMethod( );
 }
}


To instantiate a public static nested class, you do not need an instance of the outer class. You can simply use the class as is to create new instances:

import oracle.hcj.nested.OuterClass.SomeClass;
public class StaticNestedClassDemo {
 public static void main(final String[] args) {
 SomeClass obj = new SomeClass( );
 obj.someMethod( );
 }
}


With this import syntax, the class is quite easy to use. However, static nested classes can also use access specifiers. You can have public, private, protected, package, final, and even abstract static nested classes. If you try to access a static nested class outside of its visibility, your code won't compile, as the following snippet demonstrates:

package oracle.hcj.nested;
public class OuterClass {
 private static class SomeOtherClass {
 // . . . code
 }
}
package oracle.hcj.nested;
public class StaticNestedClassDemo {
 public static void main(final String[] args) {
 OuterClass.SomeOtherClass prot = 
 new OuterClass.SomeOtherClass( ); // <= Compiler error
 OuterClass.doPrivate( );
 }
}


Private and protected static nested classes have predictable visibility and specialized functions. Generally, they are used to implement internal features of a class or class hierarchy. For example, the Java collection classes use private static nested classes to implement the entries in their data structures. (For an example, see the source code to java.util.HashTable.) On the other hand, public static nested classes are often used to group classes together or give a group of classes access to private static resources. When using static nested classes, your first concern should be whether package scope is sufficient for your class. If it isn't, then by all means use static nested classes. If package scope will suffice, then it is better, for the sake of readability, to declare the class normally. Of all the nested classes, static nested classes are the easiest to use, read, and understand. Unless you positively need to access the instance variables of a class, I recommend you make your nested classes static whenever possible.

      
Comments