7.1 Overview of Nested Classes and Interfaces

A class that is declared within another class or interface, is called a nested class. Similarly, an interface that is declared within another class or interface, is called a nested interface. A top-level class or a top-level interface is one that is not nested.

In addition to the top-level classes and interfaces, there are four categories of nested classes and one of nested interfaces, defined by the context these classes and interfaces are declared in:

  • static member classes and interfaces

  • non-static member classes

  • local classes

  • anonymous classes

The last three categories are collectively known as inner classes. They differ from non-inner classes in one important aspect: that an instance of an inner class may be associated with an instance of the enclosing class. The instance of the enclosing class is called the immediately enclosing instance. An instance of an inner class can access the members of its immediately enclosing instance by their simple name.

A static member class or interface is defined as a static member in a class or an interface. Such a nested class can be instantiated like any ordinary top-level class, using its full name. No enclosing instance is required to instantiate a static member class. Note that there are no non-static member, local, or anonymous interfaces. Interfaces are always defined either at the top level or as static members.

Non-static member classes are defined as instance members of other classes, just like fields and instance methods are defined in a class. An instance of a non-static member class always has an enclosing instance associated with it.

Local classes can be defined in the context of a block as in a method body or a local block, just as local variables can be defined in a method body or a local block.

Anonymous classes can be defined as expressions and instantiated on the fly. An instance of a local (or an anonymous) class has an enclosing instance associated with it, if the local (or anonymous) class is declared in a non-static context.

A nested class or interface cannot have the same name as any of its enclosing classes or interfaces.

Skeletal code for nested classes is shown Example 7.1. Table 7.1 presents a summary of various aspects relating to nested classes and interfaces. The Entity column lists the different kinds of classes and interfaces that can be declared. The Declaration Context column lists the lexical context in which the class or interface can be defined. The Accessibility Modifiers column indicates what accessibility can be specified for the class or interface. The Enclosing Instance column specifies whether an enclosing instance is associated with an instance of the class. The Direct Access to Enclosing Context column lists what is directly accessible in the enclosing context from within the class or interface. The Declarations in Entity Body column refers to what can be declared in the class or interface body. Subsequent sections on each nested class elaborate on the summary presented in Table 7.1. (N/A in the table means not applicable.)

Example 7.1 Overview of Nested Classes and Interfaces
class TLC {                    // (1) Top level class

    static class SMC {/*...*/} // (2) Static member class

    interface SMI {/*...*/}    // (3) Static member interface

    class NSMC {/*...*/}       // (4) Non-static member (inner) class

    void nsm() {
        class NSLC {/*...*/}   // (5) Local (inner) class in non-static context
    }

    static void sm() {
        class SLC {/*...*/}    // (6) Local (inner) class in static context
    }

    SMC nsf = new SMC()
            {/*...*/};     // (7) Annonymous (inner) class in non-static context

    static SMI sf = new SMI()
            {/*...*/};     // (8) Annonymous (inner) class in static context
}

Nested type (i.e., nested classes and interfaces) can be regarded as a form of encapsulation, enforcing relationships between types by greater proximity. They allow structuring of types and a special binding relationship between a nested object and its enclosing instance. Used judiciously, they can be beneficial, but unrestrained use of nested classes can easily result in unreadable code.

Table 7.1. Overview of Classes and Interfaces

Entity

Declaration Context

Accessibility Modifiers

Enclosing Instance

Direct Access to Enclosing Context

Declarations in Entity Body

Top-level Class (or Interface)

Package

public or default

No

N/A

All that are valid in a class (or interface) body

Static Member Class (or Interface)

As static member of enclosing class or interface

All

No

Static members in enclosing context

All that are valid in a class (or interface) body

Non-static Member Class

As non-static member of enclosing class or interface

All

Yes

All members in enclosing context

Only non-static declarations + final static fields

Local Class

In block with non-static context

None

Yes

All members in enclosing context + final local variables

Only non-static declarations + final static fields

In block with static context

None

No

Static members in enclosing context + final local variables

Only non-static declarations + final static fields

Anonymous Class

As expression in non-static context

None

Yes

All members in enclosing context + final local variables

Only non-static declarations + final static fields

As expression in static context

None

No

Static members in enclosing context + final local variables

Only non-static declarations + final static fields