Nested & Inner Classes
A static nested class can be used independently, without an outer class object — accessed just as Outer.Nested.
A non-static Inner class is tied to an outer object — it can directly see the outer's instance members too.
An anonymous class is a nameless class defined for immediate, one-time use — like a button click listener.
class Outer {
static class Nested { void show() { System.out.println("Nested"); } }
class Inner { void show() { System.out.println("Inner"); } }
}- Static nested = an independent helper class
- Inner = tied to an outer object
- Anonymous = nameless, one-time use
A static nested class can be built without an object of the outer class — Outer.Nested obj = new Outer.Nested(). This is used when a helper class needs no connection to the outer instance, and is just kept inside for naming/grouping (like Map.Entry, a static nested interface inside the Map interface).
class Outer {
static class Nested {
void show() { System.out.println("Static nested!"); }
}
}
Outer.Nested n = new Outer.Nested(); // outer object nahi chahiyeTo build a non-static inner class, you first need an object of the outer class (outerObj.new Inner()). The benefit: the inner class can directly access all the outer's instance fields/methods, without explicitly passing them — because an inner class implicitly holds a reference to the outer object.
class Outer {
int x = 10;
class Inner {
void show() { System.out.println(x); } // outer ka x directly
}
}
Outer o = new Outer();
Outer.Inner i = o.new Inner(); // outer object zaroori haiYou can define a class right inside a method — a "local class". It's usable only within that method, and can capture the method's local (effectively final) variables. It's a rare use-case, but sometimes useful when a complex helper logic needs to be scoped inside just one method.
A nameless class that's defined and instantiated immediately, for one-time use — in older Java, event listeners were written exactly this way (before Java 8's lambdas). Still useful today when you need a one-time-use implementation of an interface/abstract class, and that interface isn't functional (single-method) — where a lambda wouldn't work.
Runnable r = new Runnable() {
public void run() { System.out.println("Running!"); }
};