A nested class is a class whose definition appears inside the definition of another class, as if it were a member of the other class. For example, if a program contains
class A {
class B {
// fields, methods of class B...
}
// fields, methods of class A...
}
then class B is a nested class of class A.
Code outside of the methods of class A can refer to class
B by calling it A.B, using the same
dot notation as for field and method references. Within the methods of
class A class B can be used without
qualifying the name. B could be hidden from code outside
of class A by declaring it private, just as
with fields and methods.
A nested class like B in the example above is also known as an inner class. An inner class has access to the fields of an instance of its enclosing class. For this reason, an instance of B can only be created in association with an instance of A, using the expression
/it instanceA.new A.B(...)outside of class A, where instanceA is an instance of A, and the expression
new B(...)within class A. The new instance of B knows about the enclosing instance of A and can refer to it using the expression
A.thisWe can think of an instance of an inner class as having two this references, one for itself and one for its enclosing instance. An inner class may be nested within another inner class, so an inner class can even have multiple levels of this references. Nesting inner classes more deeply than one level is uncommon, however, and should generally be avoided.
A nested class can be declared static, which restricts its access to the enclosing class to the static members of the class. For example, if B were declared static above, it could no longer access the instance variables of A, and there would be no associated instance A.this. Static nested classes are known as nested top-level classes, because they behave exactly like unnested classes except for the way they are named and the protection restrictions on access to and from the static inner class. Since static nested classes are static members of the enclosing class, they have access to all of the private static members of the enclosing class. In addition, they can be marked as private making them invisible to classes other than the enclosing class.
Instances of a static nested class are created using regular new operation, as in
new A.B(...)
We will extensively use for both static nested classes and inner classes when we present the full implementation of imperative lists.