将Java 7编译为Java 6
我知道Java 7的运行时function不适用于Java 6,但由于没有添加新的字节代码,新的字节代码invokedynamic
仅与非Java语言相关,我想知道转换有多难Java 7源代码(新的switch
语句,菱形运算符)到纯Java 6(即能够开始将源代码转换为Java 7而不会失去Java 6的兼容性)。
有什么指针吗?
标记Java 7 javac的1.6c版本(即0x32)输出的.class文件
printf“\ x00 \ x00 \ x00 \ x32”| dd of = Example.class seek = 4 bs = 1 count = 4 conv = notrunc
(根据http://en.wikipedia.org/wiki/Java_class_file#General_layout )
如果你把它(使用$ 1作为文件名)放到j6patch
你可以用以下内容完成所有类文件:
找 。 -name \ * .class | xargs -I {} ./ j6patch {}
我在一个大的(~4.8 MB jar)代码库上使用RetroTranslator
,甚至在java 6 jar上使用RetroTranslator
,因此Java 7语言function可用于在Java 5中运行的应用程序。此外,Java 7编译器( javac
)执行很多操作额外优化(例如逃逸分析)非常显着地提高了性能。
使用带有-verify -target 1.5
和JRE 1.6运行时jar的RetroTranslator
可以validation是否使用了Java 7运行时function。
据我所知,目前还没有解决这个问题的办法。 最好的办法是扩展反向转换器来处理Java 1.7结构。 钻石操作符应该非常简单,因为它根本不需要修改字节码。
您的声明“没有添加新的字节代码”是不正确的:有一个新的invokedynamic字节代码,更重要的是有几种情况下生成的字节码对1.6 JRE无效,因此反向转换器必须修复它。
你是对的,Java不使用invokedynamic指令,但是有一些其他相关的更改可以在Java中使用。 Invokedynamic依赖于新的“动态链接机制 – 方法句柄”,对invokevirtual指令也有一些更改。 您可以在本文的“新动态链接机制:方法句柄”部分中找到更多详细信息。
方法句柄也提供了更快的reflection替代方法,因此在Java中很有用。 由于该function依赖于Java 7 VM,因此无法使用方法句柄将代码转换为Java 6。
这可能是一些工作,但试试这个:
将Eclipse的Java编译器添加到类路径中。 它位于插件org.eclipse.jdt.core
(在文件夹plugins
搜索org.eclipse.jdt.core_*.jar
)。
这个JAR包含编译器和解析器。 您可以自己调用解析器,然后使用ASTVisitor
遍历解析树。
然后,您可以修改树并从中创建可以像往常一样编译的新源代码。
甚至可以在编译器生成字节代码之前“预处理”AST树; 这样可以节省“将源写回磁盘并从那里编译它们”的步骤。