What are the different types of nested/inner classes in Java (static nested, inner, local, anonymous)?

9 minintermediatenested-classesinner-classesanonymous-classes

Quick Answer

Static nested classes are top-level-like classes declared inside another class, with no reference to an outer instance. Inner (non-static) classes hold an implicit reference to their enclosing instance. Local classes are defined inside a method body. Anonymous classes are unnamed, one-off inline class definitions, often used for quick interface/abstract-class implementations before lambdas existed.

Detailed Answer

Java has four flavors of classes defined inside another class:

  1. Static nested class: declared static inside another class; behaves like a regular top-level class namespaced under the outer one, with no implicit reference to an outer instance.
class Outer {
    static class Nested { }
}
Outer.Nested n = new Outer.Nested();
  1. Inner class (non-static): each instance is tied to an enclosing Outer instance and can access its fields/methods directly (holds an implicit Outer.this reference).
class Outer {
    int x = 5;
    class Inner { int getX() { return x; } }
}
Outer o = new Outer();
Outer.Inner in = o.new Inner();
  1. Local class: defined inside a method body; visible only within that method, and can capture effectively-final local variables from the enclosing scope.
void process() {
    class Helper { void run() { /* ... */ } }
    new Helper().run();
}
  1. Anonymous class: a local class without a name, declared and instantiated in a single expression — commonly used to implement an interface or extend a class inline (before lambdas covered the single-abstract-method case).
Runnable r = new Runnable() {
    @Override public void run() { System.out.println("running"); }
};

When to use which: static nested for a helper type that doesn't need outer state (e.g., Map.Entry); inner for a type conceptually tied to an outer instance (e.g., an Iterator over a custom collection); local/anonymous for short-lived, one-off implementations — though lambdas have replaced most anonymous-class use cases for functional interfaces since Java 8.