Starting with JDK 1.1, Java provided the
ability to create nested classes. A nested class is defined inside
another class. There are two types of nested classes: static nested
classes and inner classes.

A static nested class is declared inside
another class with the static keyword or within a static context of
that class. A static class has no access to instance-specific
data.

An inner class is a nonstatic class declared
inside another class. It has access to all of its enclosing class’s
instance data, including private fields and methods. Inner classes
may access static data but may not declare static members unless
those members are compile time constants.

Deciding which type of nested class to use
depends on the data type your nested class needs to access. If you
need access to instance data, you’ll need an inner class. If you
don’t need access to instance data, a static nested class will
suffice.

The most common use of inner classes is as
event handlers for GUI-based applications. These classes are
usually declared anonymously and as needed for each component that
requires an event handler. The advantage of using an inner class
for event handling is that you can avoid large If/else statements
to decide which component is being handled. Each component gets its
own event handler, so each event handler knows implicitly the
component for which it’s working.

The snippet below creates an anonymous inner
class to handle the events created by an application’s OK
button.

Button btn = new Button(“Ok”);
btn.addActionListener(
    new ActionListener() {
        public void
actionPerformed(ActionEvent ae) {
            okClicked();

        }
    }
);

The advantage of a static nested class is that
it doesn’t need an instance of the containing class to work. This
can help you reduce the number of objects your application creates
at runtime.

The semantics for creating instances of nested
classes can be confusing. Below is a simple class that defines a
static nested class and an inner class. Pay special attention to
the main method, where an instance of each instance class is
created.

// creating an instance of the enclosing
class
NestedClassTip nt = new NestedClassTip();

// creating an instance of the inner class requires
// a reference to an instance of the enclosing class
NestedClassTip.NestedOne nco = nt.new NestedOne();

// creating an instance of the static nested class
// does not require an instance of the enclosing class
NestedClassTip.NestedTwo nct = new
NestedClassTip.NestedTwo();

public class NestedClassTip {
    private String name = “instance
name”;
    private static String staticName = “static
name”;

    public static void main(String args[])
{
        NestedClassTip nt
= new NestedClassTip();

        NestedClassTip.NestedOne
nco = nt.new NestedOne();

        NestedClassTip.NestedTwo
nct = new NestedClassTip.NestedTwo();
    }

    class NestedOne {
        NestedOne()
{
            System.out.println(name);

            System.out.println(staticName);

        }
    }

    static class NestedTwo {
        NestedTwo()
{
            System.out.println(staticName);

        }
    }
}

Nested classes can be confusing, but once you
understand their purpose and get used to the semantics, there isn’t
a lot to them. If you’d like to learn more about the details of
nested classes, check out the
Java Language Specification
.

Delivered each Thursday, our free Java newsletter provides insight and hands-on tips you need to unlock the full potential of this programming language. Automatically sign up today!