Anonymous Classes
In short: A class with no name of its own, defined directly at the spot and immediately instantiated — usually to implement an interface or an abstract class just once.
In more detail: Frequently used for one-off event handlers or callback implementations, where a separate, named class isn’t worth it. Since Java 8, lambda expressions usually take over this role for functional interfaces (interfaces with exactly one method) more compactly.
Runnable r = new Runnable() {
public void run() { System.out.println("running"); }
};In Depth
An anonymous class actually creates its own .class file when compiled (e.g. OuterClass$1.class), even though it has no name of its own in the source code — the compiler internally assigns a counter-based name. Unlike a lambda expression, an anonymous class can implement more than one method and may additionally have its own fields and its own constructor-like instance initializer:
interface Formatter {
String format(int value);
}
// Anonymous class with its own field
Formatter currency = new Formatter() {
private final String symbol = "€";
@Override
public String format(int value) {
return value + " " + symbol;
}
};
System.out.println(currency.format(42)); // "42 €"Anonymous classes can access final (or effectively final, i.e. no longer reassigned) local variables of the surrounding method — this is called a closure. Since Java 8, a lambda almost always replaces the anonymous class whenever only ONE method is implemented (a so-called functional interface like Runnable or Comparator) — shorter and without the new Interface() { ... } wrapper. For interfaces with multiple methods, or when your own state is needed, the anonymous class remains necessary.
Access to the surrounding class
Unlike a normal class, an anonymous class can access both fields/methods of the surrounding (“outer”) instance AND final local variables of the method in which it’s created, at the same time:
class CounterFactory {
private int base = 100;
Runnable createCounter(int step) {
return new Runnable() {
public void run() {
// access to both "base" (outer instance)
// and "step" (final local variable)
System.out.println(base + step);
}
};
}
}Common pitfall: “effectively final”
An anonymous class may only read a local variable of the surrounding method if it is either explicitly final or “effectively final” (never reassigned after initialization). If the variable is nevertheless changed afterwards, the compiler reports an error (“local variables referenced from an inner class must be final or effectively final”) — a classic stumbling block when converting loops with mutable counter variables into callback code.
When to use an anonymous class instead of a lambda?
A lambda can ONLY implement functional interfaces (exactly one abstract method) and has no this reference of its own (it refers to the this of the surrounding class). An anonymous class is necessary when: multiple methods need to be overridden, additional fields of your own are needed, or an abstract CLASS (instead of an interface) needs to be implemented — lambdas work exclusively with interfaces.
See also: Inner Classes, Lambda, Interface