Подтвердить что ты не робот

Java Lambdas: Как это работает в JVM и это OOP?

Например, в случае анонимного внутреннего класса передается (анонимная) ссылка на объект и методы этого объекта выполняются.

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

Что происходит в JVM, когда встречаются лямбды? Где JVM хранит кодовые блоки, связанные с лямбдами (куча: молодое, старое или постоянное поколение)?

Я попытался выполнить поиск, и я получил синтаксис для использования lambdas, но не смог понять, что происходит внутри JVM, так как в JAVA все объектно-ориентированное.

  • Итак, в контексте ООП, как работают лямбды?

  • Являются ли lambdas нарушением концепций ООП?

  • Лямбда хороша для сборщика мусора, так как не создается никаких объектов не беспокоиться о проблемах памяти и освобождении памяти?

4b9b3361

Ответ 1

Я бы не стал тратить свое время на размышления о появлении лямбда-выражений, нарушающих принципы ОО. Его цель - увеличить мощность языка, а не писать код OO, я не вижу, как lambdas могут нарушать инкапсуляцию, наследование или полиморфизм.

В этой статье объясняется, как Java обрабатывает лямбда-выражения:

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

Учитывая следующий код:

List names = Arrays.asList("1", "2", "3");
Stream lengths = names.stream().map(name -> name.length());

... Он начинается довольно просто, загружая имена var и вызывает его метод .stream(), но затем он делает что-то довольно элегантное. Вместо создания нового объекта, который будет обертывать функцию Lambda, он использует новую инструкцию invokeDynamic, которая была добавлена ​​в Java 7, чтобы динамически связать этот сайт вызова с фактической функцией лямбда.

aload_1 //load the names var

// call its stream() func
invokeinterface java/util/List.stream:()Ljava/util/stream/Stream;

//invokeDynamic magic!
invokedynamic #0:apply:()Ljava/util/function/Function;

//call the map() func
invokeinterface java/util/stream/Stream.map:
(Ljava/util/function/Function;)Ljava/util/stream/Stream;

invokeDynamic - это инструкция, добавленная в Java 7, чтобы сделать JVM менее строгим и позволяет динамическим языкам связывать символы во время выполнения, а также статически ставить все связывание при компиляции кода JVM.

Лямбда-код

aload_0
invokevirtual java/lang/String.length:()
invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
areturn

Ответ 2

Лямбда-выражения не переводятся на anonymous inner classes, они используют invoke dynamic, который был введен в Java 7 для выполнения функциональных методов. Проверьте это.

Нарушают ли они OOP? Я не думаю, что тебе все равно. Lambdas делает ваш код менее подробным, понятным и "более легким" для параллелизма. И вот что вам следует заботиться.

Из комментария Brain Goetz:

Нам не платят за запись объектно-ориентированных программ или функциональных программ, нам платят за то, чтобы писать рабочие программы.

Ответ 3

  • Выражение Lambda скомпилировано с использованием invokedynamic байт-кода.
  • Реализация Lambda хранится в том же файле класса, что и специальный частный метод.
  • Создается ли объект для вызова лямбда, зависит от ситуации. В тривиальных случаях lambda преобразуется в дескриптор постоянного метода.
  • Чтобы создать экземпляр лямбды, HotSpot создает анонимный класс, который реализует лямбда-функциональный интерфейс. Этот класс не принадлежит ни одному ClassLoader.

Смотрите подробнее из руководства по спецификации Лямбда-выражения JSR.