Java 8引入了重要的新语言功能,例如lambda表达式.
语言中的这些更改是否伴随着编译的字节码中的这些重大更改,这些更改会阻止它在不使用某些反向转换器的情况下在Java 7虚拟机上运行?
阅读Java 8从lambdas中产生的字节码类型,我想起了Java 5发布的时候.当时有Retroweaver和其他工具用于转换用JDK 5编译的字节码以在JRE 1.4上运行.
还有人为Java 8 lambdas创建了这样一个后向移植工具吗?它将让Java开发人员今天开始在生产质量的Java 7 JRE上使用lambdas,而不必等待6到12个月的Java 8 GA版本.
以下是我对后向传递器应该相对容易实现的原因的分析:
Java 8 lambdas似乎没有使用Java 7不具备的任何JVM功能(例如invokedynamic),并且java.lang.invoke.LambdaMetafactory该类及其依赖项看起来像纯Java,因此应该可以在第三方库中实现它们.因此,使用JDK 8编译的字节码可以通过添加带有LambdaMetafactory副本的第三方库(在不同的包下)并通过转换字节码来使用该元数据来在JRE 7上运行.也许还会生成一些合成类和方法来绕过可访问性检查,这java.lang.invoke.MagicLambdaImpl似乎意味着.或者为所有lambdas生成匿名内部类,就像一些支持lambda的早期访问JDK一样.
Java在Java 5中引入了带有泛型的类型擦除,因此它们可以在旧版本的Java上工作.这是兼容性的权衡.我们已经失去了兼容性[1] [2] [3] - 字节码可以在更高版本的JVM上运行,但不能在早期版本上运行.这看起来是更糟糕的选择:我们丢失了类型信息,我们仍然无法在旧版本上运行为较新版本的JVM编译的字节码.发生了什么?
具体来说,我要问,如果有任何技术原因,类型擦除不能在JVM的下一个版本中删除(假设,就像以前的版本中,它的字节码将无法反正在最后版本上运行).
[3]:对于那些真正喜欢它的人来说,类型擦除可能会以类似于retrolambda的方式向后移植.
编辑:我认为关于向后兼容性的定义的讨论模糊了这个问题.
Lambda是在Java8中引入的.包含lambda表达式的代码是否会在较旧的JVM上运行,例如,对于java 1.6?我担心二进制兼容性而不是源代码兼容性.这是一个简单的是/否问题.
谢谢.
我创建了一个基于Java 8开发的可执行JAR文件。双击该JAR文件即会打开。但是由于Oracle应用程序仅支持Java 6,因此我必须安装JRE 6,但是在安装JRE 6之后,我的可执行JAR文件没有打开。
我已经在Path环境变量中设置了JDK 8 bin路径。有解决这个问题的方法吗?在系统中有两个Java版本后,为什么无法打开JAR文件?
即使系统中安装了Java的两个版本6和8,也应打开JAR。
注:请不要不上交叉编译的所有危险评.谢谢.
我有一种情况,我们需要为Java 5 JVM编译Java 6源代码(以确保JAX-WS的使用是正确的).以前我们用ant ant脚本(显然可以)这样做了,但是在迁移到Maven之后我们发现它最终以javac抱怨:
$ javac -source 1.6 -target 1.5
javac: source release 1.6 requires target release 1.6
Run Code Online (Sandbox Code Playgroud)
是否有任何对Linux(Ubuntu的11.10,86),其中使用javac可以做到这一点的Java分配?
编辑:它似乎没有,因为限制在javac是相同的.解决方案(这使得需要消失)是从默认的javac编译器改为maven-compiler-plugin中的eclipse编译器.
编辑:我发现Eclipse编译器为javadoc实用程序不同意的匿名内部类生成字节代码.我正在为此问题准备一份错误报告.