HuntExams Academy logo
JavaIntermediate#inner-classes

What are anonymous inner classes used for?

Answer

They let you instantiate a class or implement an interface with a one-off implementation inline, without a separate named class file, commonly used before lambdas for event handlers or Runnables.

Example

Runnable r = new Runnable() {
  @Override public void run() { System.out.println("running anonymously"); }
};
r.run();

Detailed explanation

An anonymous inner class is an unnamed class declared and instantiated in a single expression. It is used when you need a small, one-off implementation of an interface or a subclass with customised behaviour, without declaring a separate named class. Typical uses include event listeners, callbacks, Runnable tasks, and local method overrides. Before Java 8 introduced lambdas, anonymous classes were especially common for passing behaviour to APIs. They remain useful when a lambda cannot express the required implementation.

In Runnable r = new Runnable() { @Override public void run() { System.out.println("running anonymously"); } };, the braces define a class implementing Runnable, and new creates its instance. The variable r holds that object through the interface type. Calling r.run() executes the overridden method on the current thread; it does not start a new thread. An anonymous class can instead extend a concrete or abstract class, supplying superclass constructor arguments where required. It cannot declare an explicit constructor because it has no class name, but it can declare fields, helper methods, and instance initialisers.

Under the hood, javac normally generates a separate class file for the anonymous implementation, often with a name such as Outer$1.class. Therefore, avoiding a separate named source declaration does not mean avoiding an additional runtime class. The implementation can access enclosing members and capture local variables, but captured local variables must be final or effectively final. Effectively final means the variable is not reassigned after its initial assignment. An anonymous class created in an instance context can also access its enclosing instance; inside its methods, this refers to the anonymous object itself.

Interviewers usually expect you to distinguish anonymous classes from lambdas rather than describe them as interchangeable syntax. A lambda targets a functional interface and does not introduce its own this. An anonymous class can extend a class, implement an interface with multiple abstract methods, and maintain fields for object-specific state. Prefer lambdas for straightforward functional-interface implementations, anonymous classes for small implementations needing class features, and named classes when the logic becomes substantial or reusable.

Key points to remember

  • Declare and instantiate a one-off unnamed implementation inline.
  • Implement one interface or extend one class, including an abstract class.
  • Support fields, helper methods, and instance initialisers, but no explicit constructors.
  • Capture only final or effectively final local variables.
  • Unlike lambdas, introduce their own this and are not limited to functional interfaces.

Common mistakes candidates make

  • Assuming an anonymous class avoids generating a separate compiled class file.
  • Saying every anonymous class can be replaced with a lambda.
  • Claiming that calling Runnable.run() starts a new thread.

Likely follow-up questions

Can an anonymous class modify a captured local variable?

It cannot reassign a captured local variable because that variable must be final or effectively final. If the variable references a mutable object, the object's state may still be changed.

How does this differ between an anonymous class and a lambda?

Inside an anonymous class's instance methods, this refers to the anonymous class instance. A lambda does not introduce its own this; it uses the meaning of this from the enclosing context.

How can an anonymous class be initialised without a constructor?

Use field initialisers or an instance initialiser block for its own initialisation logic. When extending a class, pass arguments to an accessible superclass constructor in the new expression.

Interview tip: Explain the one-off implementation use case, walk through the Runnable example, and finish with one precise difference from lambdas.

Related Interview Questions

1
JavaIntermediate#inner-classes

What is a local class in Java?

Open
2
JavaBeginner#fundamentals

What is the difference between an enum and a class with constants?

Open
3
JavaIntermediate#fundamentals#java14

What are records in Java (Java 14+)?

Open