[1] This is a very common structuring idiom.
Static nested classes serve as a mechanism for defining logically related types within a context in which that
type makes sense. For example, on page 62 we showed a Permissions class that bears information about a
BankAccount object. Because the Permissions class is related to the contract of the BankAccount
classit is how a BankAccount object communicates a set of permissionsit is a good candidate to be a nested
class:
public class BankAccount {
private long number; // account number
private long balance; // current balance (in cents)
public static class Permissions {
public boolean canDeposit,
canWithdraw,
canClose;
}
// ...
}
The Permissions class is defined inside the BankAccount class, making it a member of that class.
When permissionsFor returns a Permissions object, it can refer to the class simply as
Permissions in the same way it can refer to balance without qualification: Permissions is a member
of the class. The full name of the class is BankAccount.Permissions. This full name clearly indicates
that the class exists as part of the BankAccount class, not as a stand-alone type. Code outside the
BankAccount class must use the full name, for example:
BankAccount.Permissions perm = acct.permissionsFor(owner);
If BankAccount were in a package named bank, the full name of the class would be
bank.BankAccount.Permissions (packages are discussed in Chapter 18). In your own code, you
could import the class BankAccount.Permissions and then use the simple name Permissions, but
you would lose the important information about the subsidiary nature of the class.
Static nested classes are members of their enclosing type. Static nested classes enclosed in an interface are
implicitly public; if enclosed by a class, you can declare them to be accessible in any way you like. You can,
for example, declare a class that is an implementation detail to be private. We declare Permissions to
be public because programmers using BankAccount need to use the class.
Since Permissions is a member of BankAccount, the Permissions class can access all other
members of BankAccount, including all inherited members. For example, if Permissions declared a
method that took a BankAccount object as an argument, that method would be able to directly access both
the number and balance fields of that account. In this sense the nested class is seen as part of the
implementation of the enclosing class and so is completely trusted.
There is no restriction on how a static nested class can be extendedit can be extended by any class to which it
is accessible. Of course, the extended class does not inherit the privileged access that the nested class has to
the enclosing class.
Nested enum classes are always static, although by convention the static modifier is omitted from the
enum declaration. Enum classes are described in Chapter 6.