Will the code containing lambda expressions work on an older JVM, say for java 1.6?

Lambdas were introduced in Java8. Will the code containing lambda expressions work on an older JVM, say for java 1.6? I am concerned about binary compatibility, not source compatibility. This is a simple yes / no question.

Thank.

+19
java lambda java-8
Apr 23 '17 at 7:29 on
source share
3 answers

Oracle very carefully supports the Java language and the JVM bytecode language separately. Only the Java language specification says what a program containing a lambda expression means , it does not say anything about how this program should be compiled or interpreted .

This means that nothing exists in the Java language specification, which prohibits the compilation of these lambda expressions in such a way that the resulting code can be executed using the Java 6 JVM, but there is nothing in the Java language specification to guarantee this either. Each Java provider is allowed to encode lambda expressions in any way. (Obviously, for pragmatic reasons, most of them try to match what Oracle does pretty closely. So, for example, debuggers / decompilers / tools that can understand and process lambdas encoded by Oracle javac will automatically work with bytecode, produced by the IBM J9 JDK Java compiler.)

The javac compiler that ships with the Oracle JDK encodes lambda expressions using the rather sophisticated mechanism of LambdaMetafactory , MethodHandle s, and invokedynamic . The latter was only introduced in the Java 7 JVM , so this means that the specific encoding used by the Oracles JDK javac requires at least the Java 7 JVM. But other encodings are certainly possible, none of these complex mechanisms is really necessary, it is just a performance optimization. You can, for example, encode Lambda Expressions as inner classes that will work all the way up to the Java 1.1 JVM - that's exactly how we wrote the "poor lambda" before Java 8; this is also how the original sentences for lambdas and even the early Java 8 previews implemented it, after all, the development of lambdas in Java dates even Java 7 and invokedynamic .

There is a RetroLambda compiler that compiles Java 8 JVM bytecode (and not Java source code!), Created by Oracle JDK javac to Java 7 JVM bytecode, Java 6 JVM bytecode or Java 5 JVM bytecode. Using this compiler, you can create a class file containing bytecode that will run on any Java 5 or newer JVM from Java 8 source code that uses ( almost ) all Java 8 features.

+33
Apr 23 '17 at 14:11
source share

Short answer: it depends.

If you are completely limited to Oracle javac and libraries, the answer is: no; the following reasons.

Java bytecode contains the major version number. By default, the Java 8 compiler puts java8 in the data. Any older JVM simply refuses to run this code. Perhaps, although you can tell the Java 8 compiler to create bytecode compatible with older JVMs. But: in order for the older JVM to execute such โ€œspecialโ€ class files, you need all to make its dependencies available!

And there it breaks: Lambdas uses the invokedynamic bytecode instruction, which does not exist in Java 6. And besides this, the compiler uses a lot of Java library materials when compiling lambdas - they are all added after java 6.

So, even if you manage to compile lambda using Java 6 bytecode source code, this instruction is not available, and you also need to provide all these other classes.

But: as another excellent answer explains, there are javac alternatives that allow you to use lambda on older JVMs.

But: be careful how to spend your energy. Java 6 is still dead for server-side java. Thus, the use of these alternatives is suitable for platforms such as Android, but when you are still using the Oracle Java 6 JVM, you should spend your energy upgrading this system to the current version of Java.

+16
Apr 23 '17 at 8:56 on
source share

As others said: no

Class files created by the javac compiler are versioned. Anything that comes out of Java 8 is flagged as required Java JVM by default. Older versions of the JVM will not accept the binary.

If you want to compile an older platform, you must specify javac: javac -target 6 . Once you add this option to the command line, your Java 8 compiler will require you to specify -source 6 (or below). Therefore, it will not accept code containing lambda expressions.

+9
Apr 23 '17 at 9:10
source share



All Articles