Java Notes
Complete guide to anonymous classes in Java — creating inline implementations, event handlers, comparators, and understanding when lambdas replaced anonymous classes.
An anonymous class is a class without a name that is declared and instantiated in a single expression. It's used when you need a one-time implementation of an interface or extension of a class, and creating a separate named class would be overkill.
Think of it as saying: "I need an object that does THIS, right here, right now — and I'll never need this implementation again."
Basic Syntax
// Normal approach: create a named class
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Running in named class");
}
}
// Anonymous class approach: inline implementation
Runnable anonymousRunnable = new Runnable() {
@Override
public void run() {
System.out.println("Running in anonymous class");
}
}; // Note the semicolon — it's a statement!Anonymous Class Implementing an Interface
[English] Hello, Alice! [Spanish] ¡Hola, Alice! [Japanese] こんにちは, Alice!
Anonymous Class Extending a Class
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void makeSound() {
System.out.println(name + " makes a generic sound");
}
public void describe() {
System.out.println("I am " + name);
}
}
public class Main {
public static void main(String[] args) {
// Anonymous class extending Animal
Animal cat = new Animal("Cat") {
@Override
public void makeSound() {
System.out.println(name + " says: Meow!");
}
// Can add new methods, but can't call them through Animal reference
public void purr() {
System.out.println(name + " purrs...");
}
};
Animal dog = new Animal("Dog") {
@Override
public void makeSound() {
System.out.println(name + " says: Woof!");
}
};
cat.makeSound();
dog.makeSound();
cat.describe(); // Inherited method
// cat.purr(); // ❌ Can't access! Reference type is Animal
}
}Cat says: Meow! Dog says: Woof! I am Cat
Real-World Use: Event Handling
[Button 'Submit' clicked] → Submitting form... → Validating data... → Form submitted successfully! [Button 'Cancel' clicked] → Discarding changes... → Navigating back [Button 'Delete' clicked] → WARNING: Deleting item! → Item deleted permanently
Sorting with Anonymous Comparator
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("Charlie", "Alice", "Bob", "Diana");
// Sort alphabetically (anonymous Comparator)
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
System.out.println("Alphabetical: " + names);
// Sort by length (another anonymous Comparator)
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return Integer.compare(a.length(), b.length());
}
});
System.out.println("By length: " + names);
// Sort reverse alphabetical
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
System.out.println("Reverse: " + names);
}
}Alphabetical: [Alice, Bob, Charlie, Diana] By length: [Bob, Alice, Diana, Charlie] Reverse: [Diana, Charlie, Bob, Alice]
Anonymous Class vs Lambda (Java 8+)
For functional interfaces (one abstract method), lambdas are preferred:
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
// Anonymous class (verbose)
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
// Lambda (concise) — same result
Collections.sort(names, (a, b) -> a.compareTo(b));
// Method reference (even shorter)
Collections.sort(names, String::compareTo);
System.out.println(names);
}
}When to Use Anonymous Class Over Lambda
| Use Anonymous Class When | Use Lambda When |
|---|---|
| Interface has multiple methods | Functional interface (1 method) |
| You need instance fields | Stateless operation |
You need to refer to this (anonymous class itself) | this refers to enclosing class |
| Extending a class (not just interface) | Implementing interface only |
Accessing Outer Variables
Anonymous classes can access effectively final local variables:
Anonymous Class with Abstract Class
public abstract class Template {
public final void execute() {
setup();
doWork();
cleanup();
}
protected void setup() { System.out.println("Default setup"); }
protected abstract void doWork();
protected void cleanup() { System.out.println("Default cleanup"); }
}
public class Main {
public static void main(String[] args) {
// Anonymous class extending abstract class
Template task = new Template() {
@Override
protected void setup() {
System.out.println("Custom setup: connecting...");
}
@Override
protected void doWork() {
System.out.println("Processing data...");
}
// cleanup() uses default implementation
};
task.execute();
}
}Custom setup: connecting... Processing data... Default cleanup
Common Mistakes
- Forgetting the semicolon after the closing brace:
``java Runnable r = new Runnable() { public void run() { } } // ❌ Missing semicolon! This is a statement. ``
- Trying to add a constructor:
``java new MyInterface() { // ❌ Anonymous classes cannot have constructors! // Use instance initializer block instead: { System.out.println("Initialization"); } public void method() { } }; ``
- Modifying local variables:
``java int x = 5; Runnable r = new Runnable() { public void run() { x++; // ❌ Compile error! x must be effectively final } }; ``
- Using anonymous class when lambda is simpler:
``java // ❌ Verbose for functional interface list.forEach(new Consumer<String>() { public void accept(String s) { System.out.println(s); } }); // ✅ Lambda list.forEach(s -> System.out.println(s)); // ✅✅ Method reference list.forEach(System.out::println); ``
Best Practices
- Use lambdas instead of anonymous classes for functional interfaces
- Use anonymous classes when you need multiple methods or state
- Keep anonymous classes short — if it's more than 10 lines, create a named class
- Use instance initializer blocks instead of constructors
- Be aware of
thissemantics — in anonymous class,thisrefers to the anonymous instance
Interview Questions
Q1: Can an anonymous class have a constructor? No. Since it has no name, you can't write a constructor. Use instance initializer blocks { } instead.
Q2: Can an anonymous class implement multiple interfaces? No. An anonymous class can implement ONE interface OR extend ONE class, not both and not multiple.
Q3: What is the difference between anonymous class and lambda? Lambda: only for functional interfaces, concise, this refers to enclosing class. Anonymous class: any interface/class, can have state and multiple methods, this refers to the anonymous instance.
Q4: Can we create an anonymous class from a final class? No. Anonymous class that extends another class creates a subclass. Final classes cannot be subclassed.
Q5: How does the compiler handle anonymous classes? It generates a .class file with a name like Outer$1.class, Outer$2.class, etc. Each anonymous class becomes a separate compiled class.
Q6: Can anonymous class have static members? No (pre-Java 16). Anonymous classes are inner classes and cannot have static members.
Q7: When should you use a named class instead of anonymous? When the implementation is reused in multiple places, when it's complex (many methods/fields), or when you need a constructor with parameters.
Q8: How are anonymous classes compiled? The compiler creates a separate .class file named OuterClass$1.class, OuterClass$2.class, etc. Each anonymous class gets a numbered file. This is why you see these numbered files in the bin directory — each one corresponds to an anonymous class.
Q9: Can an anonymous class implement multiple interfaces? No. An anonymous class can either extend ONE class OR implement ONE interface, not both. If you need multiple interfaces, use a named inner class or a lambda (for single-method interfaces).
Q10: What are the limitations of anonymous classes? (1) Cannot have explicit constructors (uses instance initializer instead), (2) cannot implement multiple interfaces, (3) cannot have static members, (4) cannot be reused (one-time use only), (5) can only access effectively final local variables.
Q11: When should you use lambda instead of anonymous class? Use lambda when the interface has exactly one abstract method (functional interface) and you don't need this to refer to the anonymous instance. Use anonymous class when: implementing interfaces with multiple methods, extending a class, or needing this to refer to the anonymous instance.
Q12: Can anonymous classes access local variables of the enclosing method? Yes, but only if those variables are effectively final (not modified after initialization). This restriction exists because the anonymous class may outlive the method call, and the variable's value is captured at creation time.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Anonymous Class in Java.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, oops, anonymous, class
Related Java Master Course Topics