Inner Classes and Static Nested Classes
LinkedSet now has two classes nested inside it: Node and LinkedSetIterator. One is declared static and the other is not. Let’s look at the difference between the two.
A nested class marked static has no connection to any particular instance of the enclosing class, as we saw with Node in the linked-list chapter. A nested class without static is called an inner class. Each instance of an inner class is attached to an instance of the enclosing class, and it can use that enclosing instance’s fields directly.
Node is static:
private static class Node<T> {
T value;
Node<T> next;
}
A node needs nothing from any particular LinkedSet, so Node is static and declares its own <T>.
LinkedSetIterator is an inner class:
private class LinkedSetIterator implements Iterator<T> {
private Node<T> current = head;
// ...
}
The iterator does need something from a particular set: the head node to start from. As an inner class, each LinkedSetIterator is attached to the LinkedSet that created it, so current = head reads that set’s head with no extra code. Also notice that the class uses the set’s type parameter T directly instead of declaring its own. That is another thing only an inner class can do.
Could the iterator be static instead? It could, but then it would not have access to head, and we would have to pass head, and anything else it needs, into its constructor. The iterator needs that access because it walks through one particular set. As we will see shortly, that same access also lets the iterator detect when the set changes during iteration.
As a rule of thumb, make a nested class static unless it needs the enclosing instance.