Ответ
Оба используются для создания объектов с одним методом, но имеют фундаментальные отличия.
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 переменные из окружающего контекста.
Итог: Лямбды — это современная, лаконичная и часто более производительная замена анонимным классам для реализации функциональных интерфейсов. Анонимные классы остаются актуальны, когда нужно реализовать интерфейс с несколькими методами или расширить класс.