Java Anonymous Classes

Java Anonymous Inner Classes

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.


Why Use Anonymous Classes?

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.


Anonymous Class Example (Implementing an Interface)

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.

Anonymous Class with Interface

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(); } }

Syntax Breakdown

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.


Extending a Class

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.

Anonymous Class Extending a Class

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(); } }


Advanced: Variable Capture (Effectively Final)

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).

Variable Capture Example

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(); } }


Exercise

?

Can you use an anonymous inner class to create multiple instances later?