An anonymous class is a class without a name that is declared and instantiated at the same time. It is useful when you need a small, one-time implementation of a class or interface and creating a separately named class would add unnecessary code.
Why Use Anonymous Classes?
Imagine you need an object that performs one small task, such as handling a button click, sorting data with a custom rule, or running a short piece of background logic. If that behavior is needed only once, an anonymous class can keep the implementation close to where it is used.
interface Greeting { void sayHello(); } public class Main { public static void main(String[] args) { Greeting greeting = new Greeting() { public void sayHello() { System.out.println("Hello from anonymous class"); } }; greeting.sayHello(); } }
There is no class name between new and the opening brace. Java creates an unnamed class that implements Greeting, and an object of that class is created immediately.
Basic Syntax
An anonymous class is created by using new followed by a class or interface type and a class body.
Type reference = new Type() { // Anonymous class body };
When the target is an interface, the anonymous class must implement its required abstract methods. When the target is a class, the anonymous class can extend that class and override suitable methods.
Anonymous Class Implementing an Interface
One of the most common uses is providing a one-time implementation of an interface.
interface Payment { void pay(); } public class Main { public static void main(String[] args) { Payment payment = new Payment() { public void pay() { System.out.println("Payment processed"); } }; payment.pay(); } }
The anonymous class provides the implementation directly where the object is needed. There is no separate PaymentImpl class to maintain.
Anonymous Class Extending a Class
An anonymous class can also extend a normal class and override its methods.
class Vehicle { void start() { System.out.println("Vehicle started"); } } public class Main { public static void main(String[] args) { Vehicle vehicle = new Vehicle() { public void start() { System.out.println("Car started"); } }; vehicle.start(); } }
The variable type is Vehicle, but the actual object belongs to the anonymous subclass. The overridden start() method is therefore executed.
Anonymous Classes with Methods
An anonymous class can contain fields and additional methods, but those extra members are normally useful only inside the anonymous class itself.
interface Printer { void print(); } public class Main { public static void main(String[] args) { Printer printer = new Printer() { private int count = 1; public void print() { System.out.println("Print number: " + count); } void reset() { count = 0; } }; printer.print(); } }
The reset() method exists in the anonymous class, but it is not accessible through the Printer reference because that method is not part of the interface.
Anonymous Class with a Constructor
An anonymous class cannot declare a constructor with a name because the class itself has no name. However, it can use an instance initializer to perform initialization.
class Message { void display() { System.out.println("Default message"); } } public class Main { public static void main(String[] args) { Message message = new Message() { private String text; { text = "Custom message"; } public void display() { System.out.println(text); } }; message.display(); } }
The initializer block runs when the anonymous object is created. In most modern code, however, if substantial initialization is required, a named class is often clearer.
Anonymous Classes and Local Variables
Like local classes, anonymous classes can capture local variables from their enclosing method. Such variables must be final or effectively final.
public class Main { public static void main(String[] args) { String name = "Anita"; Runnable task = new Runnable() { public void run() { System.out.println("Hello " + name); } }; task.run(); } }
The variable name is effectively final because it is not reassigned after initialization.
Important: If you reassign name after its declaration, the anonymous class cannot capture it.
Anonymous Classes and Abstract Classes
An anonymous class can provide an implementation of an abstract class when you need a quick, one-time subclass.
abstract class Animal { abstract void sound(); } public class Main { public static void main(String[] args) { Animal animal = new Animal() { void sound() { System.out.println("Dog barks"); } }; animal.sound(); } }
The anonymous class provides the missing implementation of the abstract sound() method, allowing the object to be created immediately.
Real-World Example
Anonymous classes were historically common in event-driven programming, especially when an interface represented a callback or listener.
interface TaskListener { void onComplete(); } class TaskRunner { void run(TaskListener listener) { System.out.println("Task completed"); listener.onComplete(); } } public class Main { public static void main(String[] args) { TaskRunner runner = new TaskRunner(); runner.run(new TaskListener() { public void onComplete() { System.out.println("Callback received"); } }); } }
The listener implementation is needed only for this particular call, so creating a named implementation class would add little value.
Anonymous Classes vs Lambda Expressions
Modern Java provides lambda expressions, which are often shorter and clearer when the target is a functional interface. However, anonymous classes are still useful when you need multiple methods, fields, initialization logic, or behavior that does not fit a lambda.
| Feature | Anonymous Class | Lambda |
|---|---|---|
| Class body | Yes | No |
| Multiple methods | Can define additional methods | Represents one functional method |
| Fields | Can have instance fields | Does not define instance fields in the same way |
| Functional interface | Can implement one | Requires a functional interface |
| Typical use | One-off custom class behavior | Short functional behavior |
Anonymous Class vs Local Class
| Feature | Anonymous Class | Local Class |
|---|---|---|
| Name | No class name | Has a local class name |
| Declaration | Created with an object expression | Declared separately within a method or block |
| Constructor | No named constructor | Can define constructors |
| Reuse within scope | Less convenient | Can create multiple objects |
| Best suited for | One-off implementation | More structured local helper logic |
Common Beginner Mistakes
- Creating an anonymous class when a lambda expression would be much simpler.
- Trying to declare a constructor using a class name that does not exist.
- Expecting extra anonymous-class methods to be available through the parent type reference.
- Capturing a local variable that is not final or effectively final.
- Writing a large anonymous class that would be easier to understand as a named class.
Best Practices
- Use anonymous classes for small, localized implementations.
- Prefer lambdas for simple functional-interface implementations when they improve readability.
- Use a named class when the behavior is reused or becomes substantial.
- Keep anonymous class bodies short and easy to scan.
- Do not use anonymous classes simply because Java allows them.
Quick Revision
| Concept | Key Point |
|---|---|
| Anonymous class | Unnamed class created and instantiated at the same time |
| Interface | Can be implemented directly by an anonymous class |
| Class inheritance | An anonymous class can extend a class |
| Local variables | Captured variables must be final or effectively final |
| Lambda alternative | Often preferable for simple functional-interface behavior |
Interview Insight
A strong interview answer is that an anonymous class is useful when you need a one-time implementation of a class or interface without creating a separately named class. It is especially useful when the implementation needs fields, multiple methods, or initialization that a simple lambda cannot express.
Remember: Anonymous classes are about one-off behavior. If the implementation is small and used once, they can keep code close to its purpose. If the code becomes large, reusable, or difficult to read, give it a proper class name.
Anonymous classes complete the main family of Java nested and inner-class techniques. Understanding when to use a member inner class, static nested class, local class, or anonymous class gives you a practical toolkit for organizing closely related behavior without creating unnecessary complexity.
