我知道Java 7的运行时功能不适用于Java 6,但由于没有添加新的字节代码,新的字节代码invokedynamic
仅与非-Java语言,我想知道将Java 7源代码(新的switch
语句,菱形运算符)转换为纯Java 6会有多难(即能够开始将源代码转换为Java 7而不会丢失Java 6兼容性)。
任何指针?
答案 0 :(得分:11)
据我所知,目前还没有解决这个问题的办法。最好的办法是扩展retrotranslator以处理Java 1.7结构。钻石操作符应该非常简单,因为它根本不需要修改字节码。
您的语句“没有添加新的字节代码”不正确:有一个新的invokedynamic字节代码,更重要的是有几种情况下生成的字节码对1.6 JRE无效,因此反向转换器必须修复这一点。
答案 1 :(得分:7)
使用版本1.6.0(即0x32)的Java 7 javac标记.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
,您可以使用以下命令执行所有类文件:
find . -name \*.class |xargs -I {} ./j6patch {}
我在一个大型(~4.8 MB jar)代码库上使用它,甚至在java 6 jar上使用RetroTranslator
,因此Java 7语言功能可用于在Java 5中运行的应用程序。此外,Java 7编译器(javac
)进行了许多额外的优化(例如转义分析),非常显着地提高了性能。
将RetroTranslator
与-verify -target 1.5
和JRE 1.6运行时jar一起使用可以验证是否使用了Java 7运行时功能。
答案 2 :(得分:3)
您是正确的,Java不使用invokedynamic指令,但是可以在Java中使用其他一些相关的更改。 Invokedynamic依赖于新的“动态链接机制 - 方法句柄”,对invokevirtual指令也有一些更改。您可以在{新建动态链接机制:方法句柄'部分的this article中找到更多详细信息。
方法句柄也提供了更快的反射替代方法,因此在Java中很有用。由于该功能依赖于Java 7 VM,因此无法使用方法句柄将代码转换为Java 6。
答案 3 :(得分:2)
这可能是一些工作,但试试这个:
将Eclipse的Java编译器添加到类路径中。它位于插件org.eclipse.jdt.core
中(在org.eclipse.jdt.core_*.jar
文件夹中搜索plugins
)。
此JAR包含编译器和解析器。您可以自己调用解析器,然后use the ASTVisitor
遍历解析树。
然后,您可以修改树并从中创建可以照常编译的新源代码。
甚至可以在编译器生成字节代码之前“预处理”AST树;这样可以节省“将源写回磁盘并从那里编译它们”步骤。