Sometimes developers need to use a small class that overrides some methods of another class or interface only once. In this case, declaring a new class may be superfluous. Fortunately, Java provides a mechanism for creating a class in a single statement without having to declare a new named class. Such classes are called anonymous because they don’t have name identifiers like String or MyClass (but they do have an internal name).

What is an anonymous class?

Anonymous classes enable you to declare and instantiate a class at the same time.

An anonymous class always implements an interface or extends another class (concrete or abstract). Here is the common syntax of creating an anonymous class:

new SuperClassOrInterfaceName() {

    // fields

    // overridden methods
};

The syntax of an anonymous class is an expression. And it’s similar to a constructor call except that there is a class definition contained in a block of code.

An anonymous class must override all abstract methods of the superclass. That is, all interface methods must be overridden except default methods. If an anonymous class extends a class that has no abstract methods, it doesn’t have to override anything.

Writing anonymous classes

Let’s assume we have the following interface with two methods:

interface SpeakingEntity {

    void sayHello();

    void sayBye();
}

Here is an anonymous class that represents an English-speaking person:

SpeakingEntity englishSpeakingPerson = new SpeakingEntity() {
            
    @Override
    public void sayHello() {
        System.out.println("Hello!");
    }

    @Override
    public void sayBye() {
        System.out.println("Bye!");
    }
};

The anonymous class is declared and instantiated at the same time — as an expression. It overrides both methods of the interface.

We assign an instance of the anonymous class to the variable of the interface type. Now, we can invoke overridden methods:

englishSpeakingPerson.sayHello();
englishSpeakingPerson.sayBye();

Of course, the result is

Hello!
Bye!

Let’s declare and instantiate another anonymous class:

SpeakingEntity cat = new SpeakingEntity() {

    @Override
    public void sayHello() {
        System.out.println("Meow!");
    }

    @Override
    public void sayBye() {
        System.out.println("Meow!");
    }
};

When we invoke the same methods, we obtain the following result:

Meow!
Meow!

So, englishSpeakingPerson and cat are instances of different anonymous classes that implement the same interface.

Accessing context variables

In the body of an anonymous class, it is possible to capture variables from a context where it is defined:

  • an anonymous class can capture members of its enclosing class (the outer class);
  • an anonymous class can capture local variables that are declared as final or are effectively final (i.e. the variable is not changed but it doesn’t have the final keyword).

Here is another anonymous class that implements the SpeakingEntity interface:

public class AnonymousClassExample {

    private static String BYE_STRING = "Auf Wiedersehen!"; // static constant

    public static void main(String[] args) {

        final String hello = "Guten Tag!"; // final local variable

        SpeakingEntity germanSpeakingPerson = new SpeakingEntity() {

            @Override
            public void sayHello() {
                System.out.println(hello); // it captures the local variable
            }

            @Override
            public void sayBye() {
                System.out.println(BYE_STRING); // it captures the constant field
            }
        };

        germanSpeakingPerson.sayHello();

        germanSpeakingPerson.sayBye();
    }
}

The anonymous class captures the constant field BYE_STRING and the local final variable hello. This code is successfully compiled and prints what we expect:

Guten Tag!
Auf Wiedersehen!

A declaration of a variable or a method in an anonymous class shadows any other declaration in the enclosing scope that has the same name. You cannot access any shadowed declarations by their names.

When to use anonymous classes

Generally, you should consider using an anonymous class when:

  • only one instance of the class is needed
  • the class has a very short body
  • the class is used right after it’s defined

In this topic, we’ve considered rather simple anonymous classes to understand the basic syntax, but in real-life applications, they provide a powerful mechanism for creating classes that encapsulate behaviors and pass them to suitable methods. This is a convenient way to interact with parts of our application or with some third-party libraries.

And in the next topic about anonymous classes you will become acquainted with more difficult examples and will dive into the intricacies of anonymous classes. See you soon!

Leave a Reply

Your email address will not be published.