【问题标题】:JDK 7 class file backward compatibility with JDK 6JDK 7 类文件向后兼容 JDK 6
【发布时间】:2011-10-05 16:11:18
【问题描述】:

JDK 7 的哪些特性(不包括 invokedynamic,因为它不被 java 使用)导致新的类文件版本与 JDK 6 不兼容。似乎所有特性都可以通过编译器生成胶水代码来实现。例如 switch 语句中的字符串可以使用编译器生成的重复 ifeq 语句来实现。我希望能够为编译器提供 -source 1.7 -target 1.6 标志以符合 jre 6 并同时使用 jdk 7 中的项目硬币功能。

【问题讨论】:

  • 如果您使用 javap 查看字节码或使用反编译器并对使用 JDK 7 编译器生成的 .class 文件进行逆向工程,您将看到生成的代码为“try with resource”、“binary literals”、 “unsercore in literals”、“diamond operator”也是有效的 JRE 6 代码。但是multi-catch是错误的。
  • 现在 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。我也有兴趣了解为什么会这样。
  • "switch 语句中的字符串可以使用重复的 ifeq 来实现"。实际上,为了提高性能,它会散列常量字符串并在开关中使用常量(通过 if 检查登陆)。这对于开发人员来说很难自己完成。

标签: java java-7


【解决方案1】:

我没有看过编译器的代码,但是一些新特性显然对字节码有影响。

“Simplified varargs method invocation”实际上只是一种警告抑制,但它必须在字节码中留下一些标记,以便客户端代码可以不同地显示警告。

“Try-with-resources”生成的代码可以处理正常异常以及 finally 块中引发的第二个异常。使用新的addSuppressed() 方法存储额外的异常。这并不完全是类文件格式的更改,但它显然不适用于早期的 VM。

“Multi-catch”还生成与以前的任何编译器生成的字节码略有不同。异常表中的多个条目现在将指向同一个捕获主体。

【讨论】:

  • multi catch 无关紧要,因为它仍然是有效的 50.0 字节码。
【解决方案2】:

所以让我确保我理解这一点。您想在应用程序中针对不同的 JRE 运行特定类,然后针对所有其他类?我想如果在每次使用你不想使用不同版本的类时启动一个单独的 JVM,这在理论上是可能的。这将涉及一定程度的复杂性,相当于在不相交的应用程序中的两个 JVM 之间传递信息。开箱即用它不能以这种方式工作,因为 6 中的执行环境不知道项目硬币的功能。 IIRC 你不能在 1.4 运行时使用泛型,那么这有什么不同呢?归根结底,这似乎真的不值得,那么也许我又完全错过了您的观点。

【讨论】:

  • 同意 Woot4Moo。为什么不在 JDK 7 上重新编译(尤其是在月底发布时)?为什么停留在6?您是否有未指定的约束?即便如此,这可能是比它的价值更多的工作。如果您想要字符串开关之类的东西,那么只需编写简单的 if-else 语句即可。它们同样具有可读性,可以在 6 中为您提供所需的内容。
  • @Woot4Moo - 我想你可能误解了这个问题。听起来更像是 OP 想要在 1.7 compiler 中使用 COIN 功能,同时仍然生成可以在 1.6 JRE 中运行的代码。 @Chris,为了与旧版本的 Java JRE 和库兼容,有时有充分的理由进行编译。
  • @Woot4Moo - 你还没有回答这个问题,你的假设是错误的。首先,在过去的 Java 版本中,为带有 -target 标志的早期 JRE 编译既可行又有用。二是JDK7预计两周后发布,最终候选发布。不再需要推测。
  • @Woot4Moo - 我不知道答案。可以这么说。
  • 如果有任何帮助,我找到了这个文档:download.oracle.com/javase/7/docs/technotes/tools/windows/…。不确定这个论点/练习的意义是什么。您只是想弄清楚这些功能如何兼容编译,这并不明显。我想我通常只是尝试将目标编译到目标部署环境。如果代码可以在不止一个上运行,我们会编写与早期版本兼容的代码。是的,我知道你可以在 7 上编译 6。我们以前也这样做过。我只是不明白为什么在这里争论......
猜你喜欢
  • 2011-06-09
  • 2015-12-20
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
  • 2020-05-19
相关资源
最近更新 更多