← Skill tree CS Skill Tree 0 CSCD211

Declaring Node as a Static Nested Class

Textbook: Liang

Try This First

You write private class Node<T> inside your LinkedList class (no static). Your list holds a million nodes. What hidden cost does every single node carry?

Reveal

Every node holds an invisible reference back to the LinkedList instance that created it. That is one extra object reference per node, and it prevents the garbage collector from freeing the outer list as long as any node is still reachable.

What You Need To Walk In With

How It Works

Inside your LinkedList class, the Node declaration looks like this:

public class LinkedList<E> {

    private static class Node<T> {
        T data;
        Node<T> next;

        Node(T data) {
            this.data = data;
            this.next = null;
        }
    }

    private Node<E> head;
    private int size;
}

The word static on line 3 is the critical detail. Without it, Java treats Node as a non-static inner class: every new Node<>(value) call would attach an invisible LinkedList.this pointer to the new object. That pointer:

Because Node is purely a data-holder (two fields, one constructor, no need to reach back into LinkedList), the right declaration is private static class Node<T>.

A pointer sketch for a three-element list with static Node:

head
 |
[A | -]-->[B | -]-->[C | null]

Each box = one Node<T>. No arrow points back to the LinkedList.

Compare that to the non-static case (do not write this):

head
 |
[A | - | *LL]-->[B | - | *LL]-->[C | null | *LL]
               ^---- hidden ref to LinkedList present in every node

The *LL slot is the implicit enclosing-instance reference Java injects for non-static inner classes. Making Node static removes it entirely.

Worked Example: Predict, Then Check

Read this declaration and predict what the compiler will do:

public class Stack<E> {
    private class Node<T> {   // no static
        T data;
        Node<T> next;
    }
    private Node<E> head;
}

Does this compile? If it does, what is the runtime cost compared to a static version?

Reveal

It compiles without error. Java allows non-static inner classes. However, at runtime each Node instance carries a hidden reference to its enclosing Stack instance. A stack with 10,000 elements will have 10,000 invisible Stack.this pointers, one per node, consuming extra heap and preventing the Stack from being garbage-collected while any node is reachable. The fix is to add static.

A Common Mistake

A common mistake is to drop static and write private class Node<T> because the inner class still compiles and the tests may all pass. The problem is invisible: each node silently holds a reference to the enclosing LinkedList. In a list with a large number of elements, this multiplies into significant extra memory. Worse, if you ever hold a reference to a single node (for example, in a cursor or iterator), the entire LinkedList is kept alive by the garbage collector even after all other references to the list are gone. The fix is straightforward: add static to every data-structure helper class that does not need to call methods on its container. (Source: Bloch EJ3 Item-24)

Go Deeper (optional)

Once you are comfortable with private static class Node<T>, it is worth noting the Big-O implication: removing the hidden reference field costs nothing algorithmically (it does not change O(n) traversal), but it matters in practice for memory-constrained systems or very large lists. The inner-classes material covers the full nested-class taxonomy if you want to understand exactly when a non-static inner class is the right choice, such as iterators that do need to call back into the outer collection.

Check Yourself

Close the notes and answer each one from memory, then reveal it. Pulling an idea back from memory is one of the strongest ways to make it stick.

Check your understanding

In private static class Node<T> declared inside LinkedList, what does static prevent?

Tier 1 · Liang 10e Ch 24

Why should the Node class be declared private rather than public?

Tier 1 · Liang 10e Ch 24

A LinkedList with private class Node<T> (no static) holds 50,000 elements. How many hidden enclosing-instance references exist at runtime?

Tier 2 · Liang 10e Ch 24

Which declaration is correct for a data-only Node helper inside a LinkedList that does not need to call any LinkedList methods?

Tier 1 · Liang 10e Ch 24

If you remove static from Node and then hold a reference to a single Node after removing all other references to its LinkedList, what happens to the LinkedList in memory?

Tier 3 · Liang 10e Ch 24