JavaNested & Inner Classes

Nested & Inner Classes

A nested class is simply a class defined inside another class. Java supports two flavors that behave very differently: static nested classes and non-static inner classes — and picking the right one matters, because they have different relationships to the object that contains them.

Static nested classes

A static nested class behaves like an ordinary top-level class that just happens to be namespaced inside another class. It does not need — and cannot access — an instance of the outer class. You create it directly, without ever creating an outer instance first.

A static nested class

Java
class Computer {
    static class Processor {
        String model;

        Processor(String model) {
            this.model = model;
        }

        void run() {
            System.out.println(model + " is processing.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // No Computer instance needed at all:
        Computer.Processor p = new Computer.Processor("M3 Pro");
        p.run();
    }
}
Non-static inner classes

An inner class (no static) is tied to a specific instance of the outer class. Every inner class object implicitly holds a reference to the exact outer object that created it, which means it can freely read and use that outer object's fields and methods.

A non-static inner class

Java
class Computer {
    private String owner;

    Computer(String owner) {
        this.owner = owner;
    }

    class Display { // inner class — no 'static'
        void show() {
            // can access the enclosing Computer instance's field directly
            System.out.println(owner + "'s screen is on.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Computer c = new Computer("Ava");
        // An inner instance is created THROUGH an outer instance:
        Computer.Display d = c.new Display();
        d.show(); // Ava's screen is on.
    }
}
Note
Because every inner class instance silently holds a reference back to its enclosing outer instance, an inner object can accidentally keep its outer object alive in memory for as long as the inner object exists — even if nothing else references the outer object anymore. In long-lived inner objects (event listeners, callbacks stashed in collections, and so on) this can cause subtle memory retention that's easy to miss. When you don't actually need access to the outer instance, prefer a `static` nested class to avoid the hidden reference entirely.
When to use each

Static nested class

Non-static inner class

Needs an outer instance to exist?

No — create it directly

Yes — created via outer.new Inner()

Can access outer instance fields?

No

Yes, directly

Typical use case

A helper/grouping type logically scoped to the outer class

A component that is conceptually part of one specific outer object

Memory considerations

None — behaves like a normal class

Holds a hidden reference to the outer instance; watch for retention

  • Static nested classes are independent of any outer instance — use them by default.

  • Non-static inner classes are bound to one specific outer instance and can read its state directly.

  • Reach for an inner class only when the nested type genuinely needs to interact with its enclosing object.