将 Java 7 编译为 Java 6

发布于 2024-12-07 22:37:24 字数 224 浏览 0 评论 0原文

我知道 Java 7 的运行时功能在 Java 6 中不可用,但由于没有添加新的字节代码,新的字节代码 invokedynamic 仅与非相关-Java 语言,我想知道将 Java 7 源代码(新的 switch 语句、菱形运算符)转换为纯 Java 6(即能够开始将源代码转换为 Java)有多难7 且不失去 Java 6 兼容性)。

有什么指点吗?

I'm aware that the runtime features of Java 7 are not available with Java 6 but since no new byte code has been added the new byte code invokedynamic is only relevant for non-Java languages, I was wondering how hard it would be to convert Java 7 source code (new switch statement, diamond operator) to pure Java 6 (i.e. to be able to start to convert the source to Java 7 without losing Java 6 compatibility).

Any pointers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

℉絮湮 2024-12-14 22:37:24

据我所知,目前这个问题还没有解决办法。最好的选择是扩展 retrotranslator 来处理 Java 1.7 结构。菱形运算符应该非常简单,因为它根本不需要修改字节码。

您的说法“没有添加新的字节码”是不正确的:有一个新的invokedynamic字节码,更重要的是,在某些情况下生成的字节码对于1.6 JRE无效,因此retrotranslator必须解决这个问题。

As far as I know, there is no solution for this problem at the moment. The best bet would be to extend retrotranslator to deal with Java 1.7 constructs. The diamond operator should be very easy, since it requires no bytecode modification at all.

Your statement "no new byte code has been added" is not correct: There is a new invokedynamic byte code and more importantly there are several cases where the generated bytecode will not be valid for 1.6 JREs, so retrotranslator would have to fix that.

岛徒 2024-12-14 22:37:24

将 Java 7 javac 输出的 .class 文件标记为版本 1.6.0(即 0x32)

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 5 中运行的应用程序上使用 Java 7 语言功能。 Java 7 编译器 (javac) 进行了大量额外的优化(例如转义分析),从而非常显着地提高了性能。

RetroTranslator-verify -target 1.5 和 JRE 1.6 运行时 jar 一起使用,可以验证是否没有使用 Java 7 运行时功能。

Mark a .class file output by Java 7 javac with version 1.6.0 (i.e. 0x32)

printf "\x00\x00\x00\x32" |dd of=Example.class seek=4 bs=1 count=4 conv=notrunc

(according to http://en.wikipedia.org/wiki/Java_class_file#General_layout)

If you put that (using $1 for the filename) into j6patch you can do all class files with:

find . -name \*.class |xargs -I {} ./j6patch {}

I used this on a large (~4.8 MB jar) code base and even used RetroTranslator on the java 6 jar so Java 7 language features can be used on an app that runs in Java 5. Also the Java 7 compiler (javac) does lots of extra optimizations (e.g. escape analysis) that very noticeably improves performance.

Using RetroTranslator with -verify -target 1.5 and JRE 1.6 runtime jars allows to verify that no Java 7 runtime features are used.

累赘 2024-12-14 22:37:24

你是对的,Java 不使用 invokedynamic 指令,但是还有一些其他相关的更改可以在 Java 中使用。 Invokedynamic 依赖于新的“动态链接机制 - 方法句柄”,其中对 invokevirtual 指令也进行了一些更改。您可以在本文的“A”部分中找到更多详细信息新的动态联动机制:方法句柄。

方法句柄还提供了反射的更快替代方案,因此在 Java 中很有用。使用方法句柄将代码转换为 Java 6 是不可能的,因为该功能依赖于 Java 7 VM。

You are right that invokedynamic instruction is not used by Java, however there are some other related changes which can be used in Java. Invokedynamic relies on a new 'Dynamic Linkage Mechanism - Method Handles' for which there are some changes to the invokevirtual instruction as well. You can find more details in this article in the section 'A New Dynamic Linkage Mechanism: Method Handles'.

Method handles also provide a faster alternative to reflection, and hence are useful in Java. Converting code using method handles to Java 6 would not be possible as the feature relies Java 7 VM.

与风相奔跑 2024-12-14 22:37:24

这可能需要一些工作,但请尝试以下操作:

将 Eclipse 的 Java 编译器添加到您的类路径中。它位于插件 org.eclipse.jdt.core 中(在文件夹 plugins 中搜索 org.eclipse.jdt.core_*.jar) 。

该 JAR 包含编译器和解析器。您可以自己调用解析器,然后 使用 ASTVisitor 遍历解析树。

然后,您可以修改树并从中创建新的源代码,您可以像往常一样进行编译。

甚至可以在编译器生成字节代码之前“预处理”AST 树;这将为您节省“将源代码写回磁盘并从那里编译它们”的步骤。

It's probably some work but try this:

Add Eclipse's Java Compiler to your classpath. It's in the plugin org.eclipse.jdt.core (search for org.eclipse.jdt.core_*.jar in the folder plugins).

This JAR contains the compiler and the parser. You can invoke the parser yourself and then use the ASTVisitor to traverse the parse tree.

You can then modify the tree and create the new source code from this that you can compile as usual.

It might even be possible to "preprocess" the AST tree before the compiler generates byte code; this would save you the "write sources back to disk and compile them from there" step.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文