Oracle tries very hard to keep the Java language and the JVM bytecode language separate. The Java Language Specification only says what a program that contains a lambda expression means, it doesn't say anything about how this program is supposed to be compiled or interpreted.
This means specifically that there is nothing in the Java Language Specification that forbids that lambda expressions are compiled in such a way that the resulting code can be executed by a Java 6 JVM, but there is nothing in the Java Language Specification that guarantees it either. Every Java vendor is allowed to encode lambda expressions in whatever way they want. (Obviously, for pragmatic reasons, most try to match whatever Oracle does pretty closely. That way, for example, debuggers / de-compilers / tools which can understand and reverse-engineer lambdas encoded by Oracle's javac
will automatically work with bytecode produced by IBM J9 JDK's Java compiler.)
The javac
compiler which ships with the Oracle JDK encodes lambda expressions using a rather complicated machinery of LambdaMetafactory, MethodHandles, and invokedynamic. The latter was only introduced in the Java 7 JVM, so this means that the specific encoding that Oracles JDK's javac
uses requires at least a Java 7 JVM. But other encodings are definitely possible, none of this complex machinery is truly necessary, it is just a performance optimization. You could e.g. encode Lambda Expressions as inner classes, which would work down to the Java 1.1 JVM – this is after all exactly how we have written "poor man's lambdas" up to Java 8; it's also how original proposals for lambdas and even early previews of Java 8 implemented it, after all, the development of lambdas in Java pre-dates even Java 7 and invokedynamic
.
There is a compiler called RetroLambda, which compiles Java 8 JVM bytecode (not Java source code!) produced by Oracle JDK javac
to Java 7 JVM bytecode, Java 6 JVM bytecode, or Java 5 JVM bytecode. Using this compiler, you can produce a class file containing bytecode that will run on any Java 5 or newer JVM from Java 8 source code that uses (almost) all features of Java 8.