Nested & Anonymous Classes

Classes can be declared inside other classes. Nested classes keep helpers next to the only code that uses them, can access the outer class's private members, and — in the anonymous form — let you create a one-off implementation on the spot. You'll meet all of them in real code, even though lambdas and records now replace many uses.

Static nested classes

JAVA
class Order {
    private final String id;
    private final Line[] lines;

    static class Line {
        final String product;
        final int qty;
        Line(String product, int qty) { this.product = product; this.qty = qty; }
    }

    Order(String id, Line... lines) {
        this.id = id;
        this.lines = lines;
    }

    int totalItems() {
        int n = 0;
        for (Line l : lines) n += l.qty;
        return n;
    }
}

public class Main {
    public static void main(String[] args) {
        Order o = new Order("A-17", new Order.Line("Mug", 2), new Order.Line("Lamp", 1));
        System.out.println(o.totalItems());
    }
}
Output
3

A static nested class is like a normal class that lives in the outer class's namespace (Order.Line). It doesn't need an outer object. This is the most common and usually the right kind of nested class.

Inner classes

JAVA
class Counter {
    private int count = 0;

    class Clicker {
        void click() {
            count++;
        }
    }

    int count() { return count; }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        Counter.Clicker a = counter.new Clicker();
        Counter.Clicker b = counter.new Clicker();
        a.click();
        b.click();
        b.click();
        System.out.println(counter.count());
    }
}
Output
3

A non-static nested class (an inner class) is tied to an instance of the outer class and can use its fields directly. Its unusual creation syntax (counter.new Clicker()) hints at the hidden reference it keeps. That hidden reference can cause memory leaks, so prefer static nested classes unless you need the outer object.

Local classes

JAVA
public class Main {
    public static void main(String[] args) {
        record Pair(String name, int score) {}

        Pair[] results = {new Pair("Ana", 82), new Pair("Ben", 91)};
        Pair best = results[0];
        for (Pair p : results) if (p.score() > best.score()) best = p;
        System.out.println(best);
    }
}
Output
Pair[name=Ben, score=91]

Classes, records, enums and interfaces can be declared inside a method when only that method needs them. Local records are a neat way to hold intermediate results.

Anonymous classes

JAVA
import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        String[] words = {"kiwi", "fig", "banana", "apple"};
        Arrays.sort(words, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return Integer.compare(a.length(), b.length());
            }
        });
        System.out.println(Arrays.toString(words));

        Arrays.sort(words, (a, b) -> b.compareTo(a));
        System.out.println(Arrays.toString(words));
    }
}
Output
[fig, kiwi, apple, banana]
[kiwi, fig, banana, apple]

An anonymous class defines and creates a one-off implementation in a single expression. For interfaces with a single method, a lambda (second sort) does the same far more concisely — lesson 45. Anonymous classes are still used when you need several methods or state.

Accessing variables from the enclosing method

JAVA
public class Main {
    interface Greeter { String greet(); }

    public static void main(String[] args) {
        String name = "Mei";
        Greeter g = new Greeter() {
            public String greet() { return "Hi " + name; }
        };
        System.out.println(g.greet());
    }
}
Output
Hi Mei

Local and anonymous classes (and lambdas) can use local variables of the enclosing method only if they're effectively final — never reassigned after initialisation.

Which to use?

KindUse when
Static nested class / recordA helper type closely tied to the outer class
Inner classEach instance really needs its outer object (iterators over a collection)
Local class / recordA type used inside one method only
Anonymous classA one-off implementation with several methods or state
LambdaA one-off implementation of a single-method interface

Try it yourself

Build a small linked stack using a private static nested Node class.

Try it yourself · Main.java
Edit the code, copy it into Main.java and run java Main.java (Java 25+). How to set up Java
Output
cb left: 1