Ответ 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