Лямбда-выражения в Java работают за счет следующих механизмов:
Функциональные интерфейсы: Лямбда-выражение должно быть присвоено переменной, возвращено из метода или передано в метод, тип которого является функциональным интерфейсом. Функциональный интерфейс — это интерфейс с ровно одним абстрактным методом (SAM - Single Abstract Method). Аннотация @FunctionalInterface
является опциональной, но рекомендуется для проверки компилятором.
Инвокация динамики (invokeDynamic): Вместо генерации анонимного внутреннего класса в байткоде на этапе компиляции, как это делалось для старых версий анонимных классов, Java использует инструкцию invokeDynamic
. Эта инструкция была добавлена в Java 7 для поддержки динамически типизированных языков на JVM, а в Java 8 используется для реализации лямбда-выражений и ссылок на методы. invokeDynamic
откладывает разрешение вызова метода до момента выполнения (runtime).
Что происходит 'под капотом':
На этапе компиляции:
lambda$
) в том же классе, который содержит логику лямбда-выражения. Этот метод имеет такую же сигнатуру, как и абстрактный метод функционального интерфейса.invokeDynamic
. Эта инструкция содержит ссылку на bootstrap method (LambdaMetafactory.metafactory
).На этапе выполнения (runtime):
invokeDynamic
, она первый раз вызывает bootstrap method (LambdaMetafactory.metafactory
).LambdaMetafactory.metafactory
) динамически генерирует в памяти загрузчик вызова (call site).Лямбда-выражения в Java работают за счет следующих механизмов:
Функциональные интерфейсы: Лямбда-выражение должно быть присвоено переменной, возвращено из метода или передано в метод, тип которого является функциональным интерфейсом. Функциональный интерфейс — это интерфейс с ровно одним абстрактным методом (SAM - Single Abstract Method). Аннотация @FunctionalInterface
является опциональной, но рекомендуется для проверки компилятором.
Инвокация динамики (invokeDynamic): Вместо генерации анонимного внутреннего класса в байткоде на этапе компиляции, как это делалось для старых версий анонимных классов, Java использует инструкцию invokeDynamic
. Эта инструкция была добавлена в Java 7 для поддержки динамически типизированных языков на JVM, а в Java 8 используется для реализации лямбда-выражений и ссылок на методы. invokeDynamic
откладывает разрешение вызова метода до момента выполнения (runtime).
Что происходит 'под капотом':
На этапе компиляции:
lambda$
) в том же классе, который содержит логику лямбда-выражения. Этот метод имеет такую же сигнатуру, как и абстрактный метод функционального интерфейса.invokeDynamic
. Эта инструкция содержит ссылку на bootstrap method (LambdaMetafactory.metafactory
).На этапе выполнения (runtime):
invokeDynamic
, она первый раз вызывает bootstrap method (LambdaMetafactory.metafactory
).LambdaMetafactory.metafactory
) динамически генерирует в памяти загрузчик вызова (call site).Зарегистрируйтесь или войдите, чтобы получить доступ к полным ответам на все вопросы из банка вопросов.