Anonymous Classes: The "One-Time-Only" Class
An Anonymous Class is a local class that doesn't have a name. It is used when you need to override the behavior of a class or interface for a single instance, without having to create a separate .java file or a formal subclass.
Think of it like a "Disposable" object. If you only need a special version of a class once, why go through the effort of naming it?
1. How it Looks
You declare and instantiate the class at the same time using the new keyword followed by a class or interface name.
// Syntax:
ParentType instance = new ParentType() {
@Override
void someMethod() {
// Your custom logic here
}
};
2. Examples: Class vs. Anonymous
The Standard Way (Creating a separate class)
class BarkingDog extends Animal {
@Override
void makeSound() { System.out.println("Woof!"); }
}
Animal myDog = new BarkingDog();
The Anonymous Way (Right in the middle of your code)
Animal myDog = new Animal() {
@Override
void makeSound() {
System.out.println("Woof!");
}
};
myDog.makeSound();
3. Using with Interfaces
This is extremely common in Java, especially for handling button clicks in GUI development (like JavaFX or Android) or for sorting.
Runnable myTask = new Runnable() {
@Override
public void run() {
System.out.println("Running a task in a separate thread!");
}
};
4. Key Limitations
- No Constructor: Since it has no name, you cannot write a constructor for it.
- Single Use: You cannot reuse an anonymous class elsewhere. If you need it twice, you should make it a regular class.
- Scope: It can access variables from its surrounding scope, but those variables must be final or "effectively final" (not changed after being set).
💻 Full Practical Example: The Custom Greeting
Copy this to see how to create different behaviors on the fly:
abstract class Greeting {
abstract void sayHello();
}
public class Main {
public static void main(String[] args) {
// Anonymous class for an English Greeting
Greeting english = new Greeting() {
@Override
void sayHello() {
System.out.println("Hello!");
}
};
// Anonymous class for a French Greeting
Greeting french = new Greeting() {
@Override
void sayHello() {
System.out.println("Bonjour!");
}
};
english.sayHello();
french.sayHello();
}
}
💡 The Evolution: Anonymous Classes vs. Lambdas
If you are using an Interface with only one method, Java 8+ allows you to use Lambda Expressions, which are even shorter!
- Anonymous Class:
button.setOnAction(new EventHandler() { ... }); - Lambda:
button.setOnAction(e -> System.out.println("Clicked!"));
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// 🔹 1. Using Anonymous Class
Consumer<String> handler1 = new Consumer<String>() {
@Override
public void accept(String e) {
System.out.println("Anonymous Class: Button clicked!");
}
};
handler1.accept("click");
// 🔹 2. Using Lambda Expression
Consumer<String> handler2 = (e) -> {
System.out.println("Lambda: Button clicked!");
};
handler2.accept("click");
// 🔹 3. Even shorter Lambda
Consumer<String> handler3 = e -> System.out.println("Short Lambda: Clicked!");
handler3.accept("click");
}
}
💡 Challenge: The Custom Filter
- Create an interface
Filterwith a methodboolean isValid(int value). - In your
Mainmethod, create an anonymous class that implementsFilterwhereisValidreturnstrueonly if the number is even. - Test it with a few numbers using
System.out.println().