Static Nested Classes

A static nested class is a regular class defined inside of a package level class or inside of another static nested class. They are actually defined inside the body of the parent class, not only in the same file. As with any high level facility offered by a programming language it can be of real help in structuring clear programs or it can be just the opposite of this when abused.

Static nested class facts:

  • is defined as a static member of the parent class
  • accepts all accessibility modifiers
  • it is NOT linked to an outer instance (it can live independently)
  • has direct access to static members of the parent class regardless of the access modifiers declared in the parent class
  • has direct access to all members of an instance of the parent class regardless of the access modifiers declared in the parent class

Here is a brief example of how nested classes are declared and how they access members of the parent classes.

package com.littletutorials.nested;

public class Top
{
    private static int staticCounter = 0;
    private int nestedCounter = 0;

    public static class Nested1
    {
        private static int staticCounter = 0;
        private int nestedCounter = 0;

        public static class Nested2
        {
            public Nested2(Top t, Top.Nested1 tn1)
            {
                Top.staticCounter++;
                t.nestedCounter++;
                Top.Nested1.staticCounter++;
                tn1.nestedCounter++;
            }
        }

        public Nested1(Top t)
        {
            Top.staticCounter++;
            t.nestedCounter++;
        }

        public String toString()
        {
            return
                getClass().getName() + ".nestedCounter: " + nestedCounter +
                System.getProperty("line.separator") +
                getClass().getName() + ".staticCounter: " + staticCounter;
        }
    }

    public String toString()
    {
        return
            getClass().getName() + ".nestedCounter: " + nestedCounter +
            System.getProperty("line.separator") +
            getClass().getName() + ".staticCounter: " + staticCounter;
    }

    public static void main(String[] args)
    {
        Top t = new Top();
        Top.Nested1 nested1 = new Top.Nested1(t);
        Top.Nested1.Nested2 nested2 = new Top.Nested1.Nested2(t, nested1);

        System.out.println(t);
        System.out.println(nested1);
    }
}

The example touches two characteristics of static nested classes:

  • classes can be nested at multiple levels
  • as long as the classes are on the same branch of the “nesting tree” they can access directly static members of the parent classes and, through an instance, any member of the parent classes
  • The output of the program looks something like:
    com.littletutorials.nested.Top.nestedCounter: 2
    com.littletutorials.nested.Top.staticCounter: 2
    com.littletutorials.nested.Top$Nested1.nestedCounter: 1
    com.littletutorials.nested.Top$Nested1.staticCounter: 1

    This reveals the naming convention for nested classes (Parent$Child) and the fact that actually they are independent classes. The compiler will produce the file Top$Nested1$Nested2.class for the second level nested class Nested2.

    A public static nested class can also define a main function that can be executed directly by the JVM.

    While static nested classes can help with the grouping of local interest classes and increase encapsulation when used properly, they can also break encapsulation due to unrestricted access to all members of instances of parent classes, when used badly.

    This post is part of a series explaining the Java concept of defining classes in other classes: