В чем разница между лямбда-выражением и анонимным классом в Java?

«В чем разница между лямбда-выражением и анонимным классом в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оба используются для создания объектов с одним методом, но имеют фундаментальные отличия.

1. Синтаксис и читаемость: Лямбды обеспечивают более краткий и чистый синтаксис.

// Анонимный класс (многословный)
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
    }
};

// Лямбда-выражение (лаконично)
Runnable r2 = () -> System.out.println("Hello");

2. Область видимости this:

  • В анонимном классе this ссылается на экземпляр самого анонимного класса.
  • В лямбде this ссылается на экземпляр окружающего класса, в котором лямбда объявлена.

3. Требования к интерфейсу:

  • Лямбда работает только с функциональными интерфейсами (интерфейс с одним абстрактным методом, например, Runnable, Comparator).
  • Анонимный класс может реализовывать интерфейс с любым количеством методов или даже расширять конкретный класс.

4. Производительность и компиляция:

  • Анонимный класс при компиляции создает отдельный файл .class (например, MainClass$1.class).
  • Лямбда не создает новый класс-файл на этапе компиляции. Ее реализация генерируется динамически во время выполнения с помощью инструкции invokedynamic, что может быть более эффективно.

5. Доступ к переменным: Оба могут захватывать final или effectively final переменные из окружающего контекста.

Итог: Лямбды — это современная, лаконичная и часто более производительная замена анонимным классам для реализации функциональных интерфейсов. Анонимные классы остаются актуальны, когда нужно реализовать интерфейс с несколькими методами или расширить класс.