← Back to Core Java Course | Chapter 9: OOP Advanced | Lesson 8 of 8

Java Anonymous Classes

What is an Anonymous Class?

An anonymous class lets you declare and instantiate a one-off subclass or interface implementation in a single expression, without giving it a name. It's most useful when you need a small, throwaway implementation used exactly once, like a quick event listener or comparator.

Example: What is an Anonymous Class?

java
interface Greeting {
	void greet();
}
public class Main {
	public static void main(String[] args) {
		Greeting g = new Greeting() { // one-off implementation, no name
			public void greet() {
				System.out.println("Hi!");
			}
		};
		g.greet();
	}
}

Anonymous Classes with Abstract Classes

You can extend an abstract class anonymously by supplying the body for its abstract methods inline at the point of instantiation. This skips writing a separate named subclass file for logic you'll only ever use in one place.

Example: Anonymous Classes with Abstract Classes

java
abstract class Shape {
	abstract void draw();
}
public class Main {
	public static void main(String[] args) {
		Shape s = new Shape() { // extends abstract class anonymously
			void draw() {
				System.out.println("Drawing shape");
			}
		};
		s.draw();
	}
}

Anonymous Classes as Method Arguments

Anonymous classes are commonly passed directly as arguments to methods expecting an interface or abstract type, such as Runnable or Comparator. This keeps the implementation right next to the call site instead of scattered across the codebase.

Example: Anonymous Classes as Method Arguments

java
import java.util.Arrays;
import java.util.Comparator;
public class Main {
	public static void main(String[] args) {
		Integer[] nums = {5, 2, 8};
		Arrays.sort(nums, new Comparator<Integer>() { // passed directly as an argument
			public int compare(Integer a, Integer b) {
				return b - a;
			}
		});
		System.out.println(Arrays.toString(nums));
	}
}

Accessing Local Variables

An anonymous class can read local variables from its enclosing scope, but only if those variables are effectively final (never reassigned after initialization). The compiler captures a copy at creation time, so the class can't observe later changes to the original variable.

Example: Accessing Local Variables

java
interface Printer {
	void print();
}
public class Main {
	public static void main(String[] args) {
		final String message = "Hello"; // effectively final
		Printer p = new Printer() {
			public void print() {
				System.out.println(message);
			}
		};
		p.print();
	}
}

Limitations of Anonymous Classes

Anonymous classes can't have their own named constructors, can't implement multiple interfaces at once, and get harder to read once the body grows past a few lines. For anything more complex, a lambda (for functional interfaces) or a proper named class reads far more clearly.

Example: Limitations of Anonymous Classes

java
interface Task {
	void run();
}
public class Main {
	public static void main(String[] args) {
		Task t = new Task() { // no named constructor, only one interface at a time
			public void run() {
				System.out.println("Running task");
			}
		};
		t.run();
	}
}
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.