В чем разница между лямбда-выражением и анонимным классом в 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 переменные из окружающего контекста.

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

Ответ 18+ 🔞

Давай разберём эту дичь, как есть, без соплей. Сидишь ты такой, пишешь на Java, и тут бац — нужно сделать какую-то одноразовую хуйню, объект с одним методом. И перед тобой, сука, два пути: старый, дедовский анонимный класс, и новый, модный лямбда-выражения. И они, блядь, не одно и то же, хоть и выглядят похоже для слепого крота.

1. Кто короче, тот и прав (Синтаксис) Анонимный класс — это вот эта многословная поебень, которую писали ещё при царе Горохе. Смотри, какой овердохуища код нужно было городить:

// Это пиздец, а не код. Целая простыня, чтобы сказать "напечатай 'Hello'"
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 файл, типа MyApp$1.class. Лишняя сущность, мусор. Лямбда же умнее. Она не создаёт новый класс на этапе компиляции. Вместо этого используется хитрая инструкция invokedynamic, и всё решается в рантайме. В теории это может быть быстрее и эффективнее. Хуй с горы, но факт.

5. Доступ к переменным снаружи Тут они оба на одно лицо, оба могут хватать переменные из внешнего контекста. Но есть правило, ёпта: переменная должна быть либо final, либо effectively final (то есть не меняться после инициализации). Нарушишь — компилятор тебе такую пиздюлину влепит, мало не покажется.

Итог, блядь: Лямбды — это наше всё, когда дело касается функциональных интерфейсов. Короче, чище, потенциально шустрее. Используй их, не будь мудаком. Но если тебе вдруг понадобилось реализовать интерфейс с тремя методами или отнаследоваться от какого-нибудь Thread — тут тебе прямая дорога к старому доброму анонимному классу. Он, пидарас шерстяной, всё ещё для чего-то нужен.