TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #302 6.22K
Как НЕ реализованы лямбда-выражения

Давно хотела написать о том, как выглядят лямбды внутри JVM.

Во-первых, мало кто об этом знает. Есть несколько статей и видео с конференций, но они достаточно сложные.

Во-вторых, это интересно. Для ответа на вопрос нужно представлять, как работает JVM и собрать вместе несколько концептов.

В-третьих, время не стоит на месте. Java развивается, а многие до сих пор не в курсе изменений 10летней давности.

Как устроены лямбды - вопрос непростой, поэтому будем идти небольшими шагами. В этом посте посмотрим на возможные реализации лямбд и обсудим, что с ними не так.

Часть 1: внешний вид. Как лямбды будут выглядеть в коде?

Первая догадка - использовать опыт других языков и ввести в JVM тип function:

fun(s: Integer): boolean { return s<3; }

Легко для понимания, сложно для реализации. Java - ООП язык, всё в JVM заточено под работу объектов и примитивов. Добавить новый тип данных - чудовищно огромная работа. Как функция будет хранится, вызываться и взаимодействовать с другими объектами? Будет ли она работать с дженериками? Тысячи вопросов и сложностей.

Второй вариант: пусть лямбда реализует интерфейс с одним методом:

Predicate p = i -> i<3;

Выглядит по-джавовски и отлично впишется в текущую систему. Существующие библиотеки будут работать с лямбдами по умолчанию.

Но какой объект будет присвоен переменной p?

Часть 2: реализация

Здесь тоже два варианта.

Первый - сделать внутренний класс с одним методом и создать его экземпляр.
✅ Простая реализация
❌ Придётся компилировать и загружать класс для каждой лямбды, а при каждом вызове создавать новый объект.

С учётом того, что лямбды станут основой Stream API и использоваться для обработки данных - решение ужасное и непроизводительное.

Второй вариант - компилировать код лямбды в отдельный метод и подставлять в исходный код MethodHandle.

Мы рассмотрим MethodHandle на следующей неделе, но если кратко - это указатель на метод. Компилируем исходный пример в:

public boolean lambda(Integer i) { return i<3; }
MethodHandle mh = LDC["lambda"];

И подставляем mh в исходный код:

...stream().filter(mh)...

В теории решение отличное, на практике - неподходящее.

❌ Теряется информация о входных и выходных типах, приходится проверять их в рантайме
❌ Библиотечные методы не принимают на вход MethodHandle

Как же сделаны лямбды?

Об этом поговорим на следующей неделе:
▫️ Сначала вернёмся во времена java 6 и посмотрим как вызываются методы в JVM
▫️ Изучим новую байткод инструкцию java 7 и чуть глубже обсудим MethodHandle

После этого говорить про лямбды будет легко и понятно.
  • 👍 8
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →