An anonymous inner class is an inner class without a name. Since it has no name, you cannot use it to create instances later. An anonymous inner class is always created and used at the same time.
It is typically used when you need to create a one-time-use object of a class or interface.
Anonymous classes are a concise way to create an implementation of an interface or to extend a class on the fly. They are often used in older Java code for event listeners in GUI applications (like Swing or AWT) or for creating simple Runnable tasks.
While modern Java often uses lambda expressions for the same purpose (which are even more concise), understanding anonymous classes is crucial for reading and maintaining existing Java code.
The most common use case is to provide a quick, one-off implementation for an interface.
Let's say we have an interface Greeter.
interface Greeter {
public void greet();
}
Instead of creating a whole new named class like class EnglishGreeter implements Greeter { ... }, we can create an anonymous class directly.
interface Greeter {
public void greet();
}
public class Main {
public static void main(String[] args) {
// This is the anonymous inner class
Greeter englishGreeter = new Greeter() {
@Override
public void greet() {
System.out.println("Hello, World!");
}
};
englishGreeter.greet();
}
}
The syntax new Greeter() { ... }; looks like we are instantiating an interface, but we are not. We are creating an instance of a new, unnamed class that implements the Greeter interface. The block {...} contains the implementation for the methods defined in the interface.
Anonymous classes aren't limited to just interfaces; you can also use them to extend an existing class (either abstract or concrete) and override its methods.
abstract class Machine {
public abstract void start();
}
public class Main {
public static void main(String[] args) {
// Creating an anonymous class that extends Machine
Machine myMachine = new Machine() {
@Override
public void start() {
System.out.println("Machine is starting with a custom boot sequence!");
}
};
myMachine.start();
}
}
A very important rule when working with anonymous inner classes (and lambda expressions) is variable capture.
If an anonymous class needs to use a local variable from the method where it was created, that local variable must be final or effectively final (meaning its value is never changed after it is first initialized).
interface Task {
void execute();
}
public class Main {
public static void main(String[] args) {
String prefix = "Task Output: "; // Effectively final variable
Task myTask = new Task() {
@Override
public void execute() {
// We can access 'prefix' because it never changes
System.out.println(prefix + "Running smoothly.");
}
};
// prefix = "Changed"; // If we uncomment this, the code above will break!
myTask.execute();
}
}
Can you use an anonymous inner class to create multiple instances later?