Objects, Classes & OOP Design

Nested & Inner Classes

Classes can be declared inside classes: static nested classes are just namespaced helpers, inner classes capture an enclosing instance, and local/anonymous classes live inside methods. Default to static (EJ 24); lambdas replaced most anonymous classes.
  • Static nested: no outer-instance reference — the default choice (EJ 24)
  • Inner (non-static): holds a hidden reference to the enclosing instance
  • That hidden reference can silently keep large objects from being garbage-collected
  • Local classes capture effectively-final local variables
  • Anonymous classes are mostly superseded by lambdas — except with state or multiple methods
Static nested vs inner
public class LinkedList<E> {
    private static class Node<E> {      // static: no pointer to the list — correct
        E item;
        Node<E> next;
    }

    public class Itr {                  // inner: can see LinkedList's fields via
        Node<E> current = first;        // the implicit LinkedList.this reference
    }
}

Inside an inner class, OuterClass.this names the enclosing instance; construction from outside uses outer.new Inner() — rare, and usually a hint the design wants restructuring. Local classes (declared inside a method) and anonymous classes can read local variables of the enclosing method, provided those are effectively final — same rule as lambda capture (Lambdas).

Anonymous class vs lambda
// Before Java 8:
button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) { beep(); }
});

// Since Java 8 — same semantics, minus the ceremony (EJ Item 42):
button.addActionListener(e -> beep());
Sources
  • Core Java, Volume I: Fundamentals (13th ed.)Ch. 6.3 — Inner Classes
  • Effective Java (3rd ed.)Items 24, 42