Anonymous Inner Class in Java

Naveen AnamaneniUpdated · 5 min read

Sometimes you need a class for exactly one use: a special discount for one sale, or a sort order for one list. Writing a named class in its own place for that feels like too much ceremony. An anonymous class declares the class and creates its single object in one expression, right where it's needed. It has no name, so it can't be reused, and that's the point.

Two Anonymous Classes

Anon.java▶ Try it
import java.util.Arrays;
import java.util.Comparator;
 
public class Anon {
    abstract static class Discount {
        final String name;
        Discount(String name) { this.name = name; }
        abstract long apply(long amount);
    }
 
    public static void main(String[] args) {
        Discount festival = new Discount("Festival 10%") {
            long apply(long amount) { return amount - amount / 10; }
        };
        System.out.println(festival.name + ": Rs. " + festival.apply(2000));
 
        String[] names = {"Srihitha", "Navika", "Advitha"};
        Arrays.sort(names, new Comparator<String>() {
            public int compare(String a, String b) {
                return Integer.compare(a.length(), b.length());
            }
        });
        System.out.println(Arrays.toString(names));
 
        Arrays.sort(names, (a, b) -> b.compareTo(a));
        System.out.println(Arrays.toString(names));
        System.out.println(festival.getClass().getName());
    }
}
Output
Festival 10%: Rs. 1800
[Navika, Advitha, Srihitha]
[Srihitha, Navika, Advitha]
Anon$1

How it works

  1. new Discount("Festival 10%") { ... } creates an object of a new, unnamed subclass of Discount. The argument goes to Discount's constructor, and the body implements the abstract method.
  2. new Comparator<String>() { ... } creates an object of an unnamed class that implements Comparator, here sorting names by length.
  3. The third sort uses a lambda, (a, b) -> b.compareTo(a), which is a much shorter way to implement an interface with a single abstract method (lambdas get their own lessons later in the course).
  4. The compiler names the first anonymous class Anon$1.

The Rules

RuleDetail
Extends or implementsExactly one class or one interface
ConstructorNone of its own; arguments go to the parent's constructor. Use an instance initializer block { ... } for setup
NameNone, so it can't be created again or used as a type
Access to the surrounding codeOuter instance members, and local variables that are effectively final
New methodsAllowed, but callable only from inside it (the variable's type doesn't know them)
Class fileOuter$1.class, Outer$2.class, ...

Capturing a local variable that changes later is a compile error:

Eff.java
public class Eff {
    void run() {
        int count = 0;
        Runnable r = new Runnable() {
            public void run() { System.out.println(count); }
        };
        count++;
    }
}
Compiler output
Eff.java:5: error: local variables referenced from an inner class must be final or effectively final
            public void run() { System.out.println(count); }
                                                   ^
1 error

The anonymous object gets a copy of count; if count could change afterwards, the copy and the original would disagree, so Java forbids it.

Anonymous Class or Lambda?

Use a lambda whenUse an anonymous class when
Implementing an interface with one abstract method (Comparator, Runnable)Extending a class, especially an abstract one
The code is shortImplementing several methods
You don't need this to mean the implementing objectYou need fields or state in the object

Common Mistakes

Changing a captured local variable. Use a final copy, or a field.

Long anonymous classes buried inside method calls. If it's longer than a few lines, give it a name.

Expecting extra methods to be callable from outside. festival.extraMethod() doesn't compile: the variable's type is Discount.

Interview Corner

What is an anonymous inner class?

It's a class without a name, declared and instantiated in a single expression with new Type(args) { ... }. It either extends one class or implements one interface, can't declare constructors, and can access effectively final local variables and the enclosing instance. It's used for one-off implementations; since Java 8, lambdas replace most anonymous classes that implement single-method interfaces.

Can an anonymous class have a constructor?

No, because it has no name to give the constructor. Arguments in new Type(args) are passed to the superclass constructor, and an instance initializer block can do any extra setup.

Practice

  1. Easy: Create a Runnable with an anonymous class that prints "Backup started for Navika", and run it with r.run().
  2. Harder: Sort an array of prices in descending order twice: once with an anonymous Comparator<Integer> and once with a lambda.

Quick check: Anonymous classes

4 questions
1How many classes or interfaces can an anonymous class extend or implement?
2Can an anonymous class declare a constructor?
3A captured local variable must be:
4What is the class file for the first anonymous class in Anon?

Key Takeaways

Was this tutorial helpful?

Lesson 170 of 482