JDK 7类文件向后兼容JDK 6

28

除了invokedynamic,JDK 7的哪些功能会导致新的类文件版本与JDK 6不兼容?似乎所有功能都可以通过编译器生成粘合代码来实现。例如,switch语句中的字符串可以使用由编译器生成的重复ifeq语句来实现。我想能够给编译器提供“-source 1.7”和“-target 1.6”的标志以符合JRE 6,并同时在JDK 7中使用Project Coin功能。


如果您使用javap查看字节码或使用反编译器并反向工程JDK 7编译器生成的.class文件,您将看到“try with resource”、“binary literals”、“unserscore in literals”、“diamond operator”的生成代码也是有效的JRE 6代码。但是multi-catch是错误的。 - Deniz
13
现在 JDK 7 已正式发布,它明显不支持将 Java 7 源代码编译为 Java 6 类文件:javac -source 1.7 -target 1.6 Test.java 输出 javac: source release 1.7 requires target release 1.7。我也很想知道为什么会这样。 - narthi
1
请查看此处:http://www.oracle.com/technetwork/java/javase/compatibility-417013.html - scravy
在 switch 语句中,字符串可以使用重复的 ifeq 实现。实际上,为了提高性能,它会对常量字符串进行哈希处理,并在 switch 中使用这些常量(通过 if 检查)。这对于开发人员来说可能很难自己完成。 - ChrisCantrell
2个回答

8
我没有阅读编译器的代码,但一些新功能显然必定会对字节码产生影响。
“简化可变参数方法调用”仅仅是警告抑制,但它必须在字节码中留下某些标记,以便客户端代码可以以不同方式显示警告。
“Try-with-resources” 生成的代码可以处理常规异常和在 finally 块期间抛出的第二个异常。 使用新的 addSuppressed() 方法存储额外的异常。 这并不是类文件格式的更改,但显然无法在早期的虚拟机上运行。
“多重异常捕获”也会产生微妙地不同于任何先前编译器的字节码。 异常表中的多个条目现在将指向同一个 catch 体。

多重捕获并不重要,因为它仍然是有效的50.0字节码。 - Antimony

0

所以让我确保我理解了这一点。您想针对与所有其他类不同的JRE运行应用程序中的特定类?我认为,如果在您不想使用不同版本的类的每次使用中,都会启动单独的JVM,那么这可能在理论上是可能的。这将涉及等同于在不相交的应用程序之间传递信息的复杂级别。出厂时它不会按此方式工作,因为6中的执行环境不会知道项目硬币功能。如果我没记错,您不能在1.4运行时使用泛型,那么这有什么不同呢?归根结底,它似乎真的不值得,但话说回来,也许我完全错过了您的重点。


5
@Woot4Moo - 我认为你可能误解了问题。它更像是OP想要在使用1.7 编译器的同时,生成可以在1.6 JRE中运行的代码。@Chris,有时候为了与旧版本的Java JRE和库兼容而进行编译是有好处的。 - Andy Thomas
7
@Woot4Moo - 您没有回答这个问题,您的假设是错误的。首先,在Java的早期版本中,使用“-target”标志编译为较早的JRE版本是可行且有用的。其次,JDK7预计将在两周内发布,最终版本的候选版已经可用。不再需要猜测。 - Andy Thomas
@Andy 请务必适当地回答这个问题,因为我没有做到。 - Woot4Moo
1
@Woot4Moo - 我不知道答案。说出来也没关系。 - Andy Thomas
1
如果有帮助的话,我找到了这份文档:http://download.oracle.com/javase/7/docs/technotes/tools/windows/javac.html。不确定这个参数/练习的目的是什么。似乎你只是想弄清楚这些功能是否兼容编译。我想我通常只会尝试将编译目标定位到目标部署环境。如果代码可以在多个环境上运行,我们会编写符合早期版本的代码。是的,我知道你可以在7上编译6。我们以前也做过这样的事情。我只是不明白为什么要在这里争论..... - Chris Aldrich
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接