Ответ 1
Oracle очень старательно поддерживает язык Java и байт-код JVM язык отдельно. Только спецификация языка Java говорит, что означает программа, содержащая выражение лямбда, она ничего не говорит о как эта программа должна быть скомпилирована или интерпретирована.
Это означает, что в спецификации языка Java ничего не существует, что запрещает компиляцию этих лямбда-выражений таким образом, что результирующий код может быть выполнен с помощью Java 6 JVM, но в спецификации языка Java нет ничего, что гарантировало бы это тоже. Каждому поставщику Java разрешено кодировать лямбда-выражения любым способом. (Очевидно, что по прагматичным причинам большинство из них пытаются сопоставить то, что делает Oracle довольно близко.Таким образом, например, отладчики/декомпилирующие/инструменты, которые могут понимать и перерабатывать lambdas, закодированные Oracle javac
, будут автоматически работать с байт-кодом, произведенным компилятором IBM J9 JDK Java.)
Компилятор javac
, который поставляется с Oracle JDK, кодирует лямбда-выражения с использованием довольно сложного механизма LambdaMetafactory
, MethodHandle
s и invokedynamic
. Последний был только представлен в Java 7 JVM, поэтому это означает, что для конкретной кодировки, используемой Oracles JDK javac
, требуется, по крайней мере, Java 7 JVM. Но другие кодировки, безусловно, возможны, ни один из этих сложных механизмов не является действительно необходимым, это просто оптимизация производительности. Вы можете, например, закодировать Lambda Expressions как внутренние классы, которые будут работать вплоть до Java 1.1 JVM - это ведь точно, как мы написали "бедный человек лямбда", до Java 8; это также то, как оригинальные предложения для lambdas и даже ранние предварительные просмотры Java 8 реализовали его, в конце концов, развитие lambdas в Java заранее датируется даже Java 7 и invokedynamic
.
Существует компилятор RetroLambda, который компилирует байт-код Java 8 JVM (а не исходный код Java!), созданный Oracle JDK javac
к Java 7 JVM bytecode, Java 6 JVM bytecode или Java 5 JVM bytecode. Используя этот компилятор, вы можете создать файл класса, содержащий байт-код, который будет запускаться на любом Java 5 или более новом JVM из исходного кода Java 8, который использует (почти) все функции Java 8.