Java Anonymous Class
Run each complete program separately. Its required helper classes and imports are included in the same code block. Short syntax fragments explain individual operations.
An anonymous class creates a small unnamed implementation at the place where an object is needed. It can extend a class or implement an interface. The declaration and object creation appear together, so it is useful for behavior that does not need a separate named class.
It is mainly used when we need to create a one-time implementation of a class or interface without creating a separate named class.
For example:
interface Greeting {
void sayHello();
}
public class HelloWorld {
public static void main(String[] args) {
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello!");
}
};
greeting.sayHello();
}
}Output
Hello!Here:
new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello!");
}
}creates an anonymous class that implements the Greeting interface.
The class has no name, so it is called an anonymous class.
What is an Anonymous Class?
An anonymous class is a special type of inner class that:
- Does not have a class name.
- Is declared and instantiated in a single expression.
- Can extend a class or implement an interface.
- Is useful when an implementation is required only once.
- Can override methods of a parent class or interface.
- Can access members of the enclosing class.
General syntax
For implementing an interface:
InterfaceName object = new InterfaceName() {
@Override
public void method() {
// implementation
}
};For extending a class:
ParentClass object = new ParentClass() {
@Override
public void method() {
// implementation
}
};Notice that there is no class name between new ParentClass() and {.
Why is it Called Anonymous?
Consider a normal class:
class Student {
void study() {
System.out.println("Student is studying");
}
}The class has a name:
StudentBut with an anonymous class:
Student student = new Student() {
@Override
void study() {
System.out.println("Student is studying");
}
};There is no name for the new class.
Therefore, it is called an anonymous class.
Anonymous Class vs Normal Class
Normal class
class Dog {
void sound() {
System.out.println("Dog barks");
}
}Object creation:
Dog dog = new Dog();The class has a name:
DogAnonymous class
Dog dog = new Dog() {
@Override
void sound() {
System.out.println("Dog makes a sound");
}
};The subclass created here does not have a name.
Anonymous Class with an Interface
One of the most common uses of anonymous classes is implementing an interface.
Consider:
interface Payment {
void pay();
}We can implement it using a normal class:
class CreditCardPayment implements Payment {
@Override
public void pay() {
System.out.println("Payment using credit card");
}
}Then:
Payment payment = new CreditCardPayment();
payment.pay();But if we need the implementation only once, we can use an anonymous class.
interface Payment {
void pay();
}
public class HelloWorld {
public static void main(String[] args) {
Payment payment = new Payment() {
@Override
public void pay() {
System.out.println("Payment using credit card");
}
};
payment.pay();
}
}Output
Payment using credit cardHere:
new Payment() {
@Override
public void pay() {
System.out.println("Payment using credit card");
}
}creates an anonymous implementation of Payment.
Anonymous Class Extending a Class
An anonymous class can also extend a normal class.
Consider:
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}We can create an anonymous subclass:
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
public class HelloWorld {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void sound() {
System.out.println("Dog barks");
}
};
animal.sound();
}
}Output
Dog barksThe anonymous class extends Animal and overrides its sound() method.
Conceptually, it is similar to:
class SomeUnnamedClass extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}But Java does not allow us to explicitly give this anonymous class a name.
Anonymous Class with an Abstract Class
Anonymous classes are frequently used to provide an implementation for an abstract class.
Example
abstract class Vehicle {
abstract void start();
}We can create an anonymous subclass:
abstract class Vehicle {
abstract void start();
}
public class HelloWorld {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle() {
@Override
void start() {
System.out.println("Vehicle starts with a button");
}
};
vehicle.start();
}
}Output
Vehicle starts with a buttonThe anonymous class provides the implementation of the abstract method.
Anonymous Class Can Override Multiple Methods
An anonymous class can override multiple methods inherited from its parent.
Example
class Animal {
void sound() {
System.out.println("Animal sound");
}
void eat() {
System.out.println("Animal eats");
}
}Anonymous implementation:
class Animal {
void sound() {
System.out.println("Animal sound");
}
void eat() {
System.out.println("Animal eats");
}
}
public class HelloWorld {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void sound() {
System.out.println("Dog barks");
}
@Override
void eat() {
System.out.println("Dog eats food");
}
};
animal.sound();
animal.eat();
}
}Output
Dog barks
Dog eats foodAnonymous Class Can Have Its Own Methods
An anonymous class can declare additional methods.
Example
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
public class HelloWorld {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void sound() {
System.out.println("Dog barks");
}
void run() {
System.out.println("Dog runs");
}
};
animal.sound();
}
}Output
Dog barksNotice that we cannot directly call:
animal.run();because the reference type is:
Animaland run() is not declared in Animal.
The method exists in the anonymous class, but it is not accessible through the Animal reference.
Anonymous Class with Constructor
An anonymous class does not have a constructor with a name because the class itself has no name.
However, the constructor of the parent class can be called.
Example
class Employee {
Employee(String name) {
System.out.println("Employee: " + name);
}
void work() {
System.out.println("Employee works");
}
}
public class HelloWorld {
public static void main(String[] args) {
Employee employee = new Employee("Ashish") {
@Override
void work() {
System.out.println("Employee is working on Java");
}
};
employee.work();
}
}Output
Employee: Ashish
Employee is working on JavaThe expression:
new Employee("Ashish")calls the constructor of Employee.
The anonymous class itself does not have a separately declared constructor.
Anonymous Class with Interface Having Multiple Methods
An anonymous class must provide implementations for all required abstract methods of the interface, unless the interface is otherwise handled through inheritance/default methods.
Example
interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
}Anonymous implementation:
interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
}
public class HelloWorld {
public static void main(String[] args) {
Calculator calculator = new Calculator() {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int subtract(int a, int b) {
return a - b;
}
};
System.out.println(calculator.add(10, 5));
System.out.println(calculator.subtract(10, 5));
}
}Output
15
5Anonymous Class and Access to Outer Class Members
An anonymous class can access members of its enclosing class.
Example
class Outer {
private int number = 100;
void display() {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(number);
}
};
runnable.run();
}
}
public class HelloWorld {
public static void main(String[] args) {
Outer outer = new Outer();
outer.display();
}
}Output
100The anonymous class can access the private member:
numberof the enclosing class.
Using this in an Anonymous Class
Inside an anonymous class, this refers to the anonymous class object.
Example
interface Greeting {
void message();
}
public class HelloWorld {
public static void main(String[] args) {
Greeting greeting = new Greeting() {
@Override
public void message() {
System.out.println(this.getClass().getName());
}
};
greeting.message();
}
}Here:
thisrefers to the current anonymous class instance.
It does not refer to the outer class.
Using OuterClass.this
If an anonymous class is inside an outer class and we want to explicitly refer to the outer object, we can use:
OuterClass.thisExample
class Outer {
int number = 100;
void display() {
Runnable runnable = new Runnable() {
int number = 200;
@Override
public void run() {
System.out.println(number);
System.out.println(Outer.this.number);
}
};
runnable.run();
}
}
public class HelloWorld {
public static void main(String[] args) {
new Outer().display();
}
}Output
200
100Here:
numberrefers to the anonymous class field.
While:
Outer.this.numberrefers to the outer class field.
Anonymous Class with final Variables
An anonymous class can access local variables from the enclosing method when those variables are final or effectively final.
Example
public class HelloWorld {
public static void main(String[] args) {
int number = 100;
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(number);
}
};
runnable.run();
}
}Output
100Here number is effectively final because its value is never changed.
This is allowed.
But this is not allowed:
int number = 100;
number = 200;
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(number);
}
};The local variable is no longer effectively final.
Anonymous Class with Event Handling
Anonymous classes were traditionally very common in event-driven programming.
For example, an event listener might be implemented like this:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});Instead of creating a separate class such as:
class ButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
}we can provide the implementation directly where it is needed.
Anonymous Class with Thread
Anonymous classes can also be used with Runnable.
Example
public class HelloWorld {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Task is running");
}
};
Thread thread = new Thread(task);
thread.start();
}
}Possible output
Task is runningThe anonymous class implements Runnable.
Anonymous Class vs Lambda Expression
Java 8 introduced lambda expressions, which often provide a shorter alternative to anonymous classes.
Consider:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Task is running");
}
};The same thing can be written using a lambda:
Runnable runnable = () -> {
System.out.println("Task is running");
};For a functional interface, a lambda is often more concise.
What is a Functional Interface?
A functional interface is an interface that has exactly one abstract method.
Example
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}It can be implemented using a lambda:
Calculator calculator = (a, b) -> a + b;However, anonymous classes are more flexible because they can be used with:
- interfaces that are not functional interfaces
- abstract classes
- classes that need multiple overridden methods
- situations where an actual class body is useful
Anonymous Class vs Lambda
| Feature | Anonymous Class | Lambda |
|---|---|---|
| Has class body | Yes | Yes, but limited to lambda syntax |
| Can extend a class | Yes | No |
| Can implement interface | Yes | Functional interfaces only |
| Multiple abstract methods | Yes, when implementing an interface normally | No |
| Can have fields | Yes | No independently declared instance fields |
| Can have constructors | No explicit constructor | No |
| Syntax | Longer | Shorter |
| Common use | One-time class/interface implementation | Functional interface implementation |
Anonymous Class vs Named Inner Class
Named inner class
class Outer {
class Printer {
void print() {
System.out.println("Printing");
}
}
}Creation:
Outer outer = new Outer();
Outer.Printer printer = outer.new Printer();
printer.print();The class has a name:
PrinterAnonymous class
class Outer {
void display() {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Printing");
}
};
runnable.run();
}
}The class has no explicit name.
Anonymous Class with an Interface and Variables
An anonymous class can contain its own instance variables.
Example
interface Message {
void show();
}
public class HelloWorld {
public static void main(String[] args) {
Message message = new Message() {
String text = "Hello from anonymous class";
@Override
public void show() {
System.out.println(text);
}
};
message.show();
}
}Output
Hello from anonymous classThe anonymous class contains its own field:
String textAnonymous Class with Multiple Objects
Every time we write a separate anonymous-class expression, a separate anonymous class implementation can be created.
Example
interface Greeting {
void greet();
}
public class HelloWorld {
public static void main(String[] args) {
Greeting english = new Greeting() {
@Override
public void greet() {
System.out.println("Hello");
}
};
Greeting hindi = new Greeting() {
@Override
public void greet() {
System.out.println("Namaste");
}
};
english.greet();
hindi.greet();
}
}Output
Hello
NamasteBoth objects use different anonymous implementations.
Anonymous Class with Method Parameters
An anonymous class can also be passed directly as an argument.
Example
interface Notification {
void send();
}
class NotificationService {
void notifyUser(Notification notification) {
notification.send();
}
}
public class HelloWorld {
public static void main(String[] args) {
NotificationService service = new NotificationService();
service.notifyUser(new Notification() {
@Override
public void send() {
System.out.println("Notification sent");
}
});
}
}Output
Notification sentThis is useful when the implementation is needed only for that particular method call.
Anonymous Class with Return Type
A method can return an anonymous class object.
Example
interface Greeting {
void greet();
}
class GreetingFactory {
static Greeting createGreeting() {
return new Greeting() {
@Override
public void greet() {
System.out.println("Hello from greeting");
}
};
}
}
public class HelloWorld {
public static void main(String[] args) {
Greeting greeting = GreetingFactory.createGreeting();
greeting.greet();
}
}Output
Hello from greetingImportant Rules of Anonymous Classes
1. An anonymous class has no explicit name
Example
new Animal() {
};There is no class name after new.
2. It is created and declared together
Example
Animal animal = new Animal() {
};The class declaration and object creation happen in the same expression.
3. It can extend one class
Java supports single class inheritance.
Therefore, an anonymous class can extend only one parent class.
Example
Animal animal = new Animal() {
};4. It can implement an interface
Example
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Running");
}
};5. It can override methods
Example
Animal animal = new Animal() {
@Override
void sound() {
System.out.println("Dog barks");
}
};6. It can contain fields
Example
Runnable task = new Runnable() {
int count = 10;
@Override
public void run() {
System.out.println(count);
}
};7. It can access enclosing-class members
An anonymous class can access members of its enclosing class, subject to normal Java access rules.
8. Local variables must be final or effectively final
Example
int number = 10;
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println(number);
}
};This works because number is effectively final.
Anonymous Class Cannot Have a Constructor
You cannot declare a constructor for an anonymous class like this:
new Animal() {
Animal() {
// Invalid approach
}
};An anonymous class has no class name that can be used as a constructor name.
If initialization is required, an instance initializer block can be used.
Example
Animal animal = new Animal() {
{
System.out.println("Anonymous class initialized");
}
@Override
void sound() {
System.out.println("Dog barks");
}
};Output
Anonymous class initializedThe instance initializer runs when the anonymous object is created.
Real-World Uses of Anonymous Classes
Anonymous classes are useful when:
1. One-time implementation
When an implementation is needed only once.
2. Event handling
Common in older GUI/event-driven Java code.
3. Callbacks
A callback implementation can be supplied directly.
4. Multithreading
They can implement Runnable or similar interfaces.
5. Testing
They can provide small custom implementations for test scenarios.
6. Framework APIs
Some Java APIs historically use anonymous classes for listeners, handlers, callbacks, and custom behavior.
Complete Example
The following example demonstrates an anonymous class extending an abstract class.
abstract class Employee {
String name;
Employee(String name) {
this.name = name;
}
abstract void work();
void displayName() {
System.out.println("Employee: " + name);
}
}
public class HelloWorld {
public static void main(String[] args) {
Employee employee = new Employee("Ashish") {
@Override
void work() {
System.out.println("Employee is developing a Java application");
}
};
employee.displayName();
employee.work();
}
}Output
Employee: Ashish
Employee is developing a Java applicationExplanation
This statement:
Employee employee = new Employee("Ashish") {does three things conceptually:
- Creates a subclass of
Employee. - Provides an implementation for
work(). - Creates an object of that anonymous subclass.
The variable:
employeehas the reference type:
Employeeso it can access the methods available through Employee.
Anonymous Class and Polymorphism
Anonymous classes are closely related to runtime polymorphism.
Example
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
public class HelloWorld {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void sound() {
System.out.println("Dog barks");
}
};
animal.sound();
}
}Output
Dog barksThe reference type is:
Animalbut the actual object is an instance of the anonymous subclass.
Therefore, the overridden method is executed at runtime.
Common Mistakes
Mistake 1: Trying to give an anonymous class a name
Incorrect:
new Animal class Dog() {
};Anonymous classes do not have an explicit class name.
Correct:
new Animal() {
};Mistake 2: Forgetting the semicolon
An anonymous class expression used as an assignment needs a semicolon after the closing brace.
Correct:
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Running");
}
};Notice:
};Mistake 3: Missing interface method implementation
If the interface has abstract methods, the anonymous class must implement them unless the anonymous class remains abstract—which is not possible for an object creation expression.
For example:
interface Test {
void method1();
void method2();
}The implementation needs both:
Test test = new Test() {
@Override
public void method1() {
}
@Override
public void method2() {
}
};Mistake 4: Trying to call an anonymous-only method through the parent reference
Example
Animal animal = new Animal() {
void run() {
System.out.println("Running");
}
};This will not work:
animal.run();because run() is not part of the Animal type.
Mistake 5: Modifying a local variable captured by the anonymous class
This is not allowed:
int number = 10;
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println(number);
}
};
number = 20;The local variable must remain final or effectively final when captured.
Anonymous Class Syntax Summary
Implementing an interface
InterfaceName object = new InterfaceName() {
@Override
public void method() {
// implementation
}
};Extending a class
ParentClass object = new ParentClass() {
@Override
void method() {
// implementation
}
};Extending an abstract class
AbstractClass object = new AbstractClass() {
@Override
void abstractMethod() {
// implementation
}
};Anonymous Class vs Local Class
| Feature | Anonymous Class | Local Class |
|---|---|---|
| Declared inside method/block | Yes | Yes |
| Has a class name | No | Yes |
| Can have methods | Yes | Yes |
| Can have fields | Yes | Yes |
| Can have constructor | No explicit constructor | Yes |
| Best for | One-time implementation | Reusable within the method |
| Syntax | Shorter for one-time use | More structured |
Anonymous Class vs Lambda Expression
Use an anonymous class when:
- You need to extend a class.
- You need to implement a non-functional interface.
- You need multiple methods.
- You need fields or more complex class-specific behavior.
- You need a full class body.
Use a lambda when:
- You are working with a functional interface.
- The implementation is small.
- You want concise code.
Example
Anonymous class
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Running");
}
};Lambda
Runnable task = () -> {
System.out.println("Running");
};Key Points
- An anonymous class is a class without an explicit name.
- It is declared and instantiated in the same expression.
- It can extend a class.
- It can implement an interface.
- It can extend an abstract class and implement its abstract methods.
- It can override inherited methods.
- It can contain fields and additional methods.
- It can access members of its enclosing class.
- Local variables captured by it must be final or effectively final.
- An anonymous class cannot have an explicitly declared constructor.
- It is useful when an implementation is required only once.
- Lambda expressions are often a shorter alternative for functional interfaces.
- Anonymous classes are more flexible than lambdas because they can extend classes and provide more general class behavior.
- The reference type determines which members can be accessed through the reference.
- The actual anonymous object determines overridden behavior at runtime.
Conclusion
A Java Anonymous Class provides a convenient way to create a one-time implementation of a class or interface without creating a separate named class.
The basic pattern is:
InterfaceName object = new InterfaceName() {
@Override
public void method() {
// implementation
}
};Anonymous classes are especially useful for callbacks, event handling, multithreading, testing, and one-time implementations.
Although lambda expressions have replaced many simple anonymous-class use cases, anonymous classes remain important when working with abstract classes, non-functional interfaces, multiple methods, or more complex one-time class behavior.
The key idea to remember is:
An anonymous class is an unnamed class that is declared and instantiated at the same time.
See you in next page....🙂