Lambda vs Anonymous Class in Java

1. Introduction

In Java, both lambda expressions and anonymous classes instantiate objects from interfaces or abstract classes without the need to create a traditional class implementation. A lambda expression is a concise way to represent an instance of a functional interface (an interface with a single abstract method) using an arrow syntax (->). An anonymous class is a more verbose way to define an instance of a class without giving it a name.

2. Key Points

1. Lambda expressions are shorter and generally more readable than anonymous classes.

2. Anonymous classes can implement interfaces with more than one method and can extend concrete classes.

3. Lambda expressions can access final or effectively final variables from their enclosing scope. Anonymous classes can access any final variables.

4. Lambda expressions cannot have a state (cannot contain instance variables), while anonymous classes can have a state.

3. Differences

Lambda Expression Anonymous Class
Introduced in Java 8 to provide a clear and concise way to represent one method interface using an expression. It has been in Java since version 1.1, allowing the declaration and instantiation of a class at the same time.
Primarily used to implement functional interfaces (interfaces with only one abstract method). It can be used to implement any interface, regardless of the number of abstract methods, or to extend a class.
Lambda expressions can only access final or effectively final variables outside their scope. Anonymous classes can access final and non-final variables, but local variables are restricted similarly to lambda expressions.
The syntax is more concise and expressive, making the code easier to read and write for functional programming. The syntax is more verbose, making the code harder to read, especially for simple implementations or where only a single method is needed.
There is no direct way to access this reference; this refers to the enclosing class where the lambda is written. It has its own reference, which refers to the anonymous class itself.
It cannot define any new methods except the method body it abstracts; it's purely functional. It can override methods and declare new methods and fields within its body.
Better suited for short operations or passing functionality as an argument. It is more suitable when you need to initialize a complex instance of a class with multiple methods or when implementing multiple methods of an interface.

4. Example

// Using a lambda expression
Runnable r1 = () -> System.out.println("Hello World with lambda!");

// Using an anonymous class
Runnable r2 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World with anonymous class!");
    }
};

public class Main {
    public static void main(String[] args) {
        r1.run();
        r2.run();
    }
}

Output:

Hello World with lambda!
Hello World with anonymous class!

Explanation:

1. The lambda expression r1 implements the Runnable interface's run method in a single line of code.

2. The anonymous class r2 also implements the Runnable interface but requires more syntax.

3. Both r1 and r2 provide the same functionality, but r1 is more concise.

5. When to use?

- Use lambda expressions for cleaner and more readable code when working with functional interfaces.

- Use anonymous classes when you need to work with abstract classes or interfaces with more than one method or when you need to maintain state within the class.

Comments