【问题标题】:Will JRE 1.4 support classes compiled with Java 1.5 & 1.6?JRE 1.4 是否支持使用 Java 1.5 和 1.6 编译的类?
【发布时间】:2009-11-10 20:23:29
【问题描述】:

使用 1.5 和 1.6 编译的代码会在 1.4 JRE 上运行吗?我们不确定 1.4 JRE 支持哪些 Java 版本。

我们知道,如果有问题的代码实现了 1.5 或 1.6 支持的功能,那么它肯定是 won't compile... 并且有一些 risks 带有“向后编译”但不确定 1.4 JRE 是否会拒绝甚至是否加载 1.5/1.6 编译的类。


更新:我确认如果您在 JRE 1.4 上运行 1.6 类文件,您会收到 java.lang.UnsupportedClassVersionError 异常。

【问题讨论】:

    标签: javac java backwards-compatibility


    【解决方案1】:

    您可以交叉编译。本文档向您展示了如何:

    http://java.sun.com/javase/6/docs/technotes/tools/solaris/javac.html#crosscomp-example

    您必须指定您所针对的特定主要版本(1.4,听起来像)。

    使用这种技术,您最好的选择是始终使用您能找到的最新的 javac!这样您就可以获得所有最新的错误修复和性能改进,而且非常安全。

    编辑:请注意,这确实解决了库不兼容的问题,这在几个答案中进行了讨论!

    【讨论】:

    • 我强烈反对。如果您不想使用需要部署的版本的 JDK 附带的 javac,请改用 Eclipse 编译器,并在需要部署的 Java 版本下运行。我相信 Eclipse 编译器在过去 5 年中比 javac 更受关注。
    【解决方案2】:

    仅当您使用javac -target 1.4 开关进行编译时。

    显然您将无法使用 1.5+ 的功能,例如泛型、执行器等。

    【讨论】:

    • 只使用 -target 而没有 sun.com 链接中的其他建议(请参阅我的回答)是危险的。
    • 不使用开关会怎样? JRE 1.4 会引发错误吗?
    • 它很可能会给你一个类不兼容错误或类似的错误。
    • 我在尝试这样做时遇到了“版本主要次要”错误。
    • 不,问题只是您的代码可能不小心使用了旧版本平台中不存在的库方法。结果:运行时出现 NoSuchMethodError 等。
    【解决方案3】:

    如果您只是使用默认的 javac 1.6 构建,您的类文件将无法在旧版本的 Java 上运行。

    为旧版 Java 编译的最佳方法是使用 older JDK releases。但是,如果您真的想尝试从较新的 Java 编译较旧的 Java,这里有一些说明:

    【讨论】:

    • 不,编译旧 Java 的最佳方法是不要使用旧版本,因为它们存在 错误 和性能问题。我在回答中分享的建议——始终使用你能获得的最新版本,但遵循正确的交叉编译建议——来自 Peter von der Ahe,他是 javac 几年的技术主管,直到最近。
    • 编译器中的错误很少,所以这并不合适。此外,即使使用 -target 开关,仍然可以包含 1.6 中存在但 1.4 中不存在的方法调用(例如 string.split())。没有多少 -target 开关可以解决这个问题。另一方面,使用较旧的 JDK 进行编译可确保您不会因 JDK 的较旧或较新版本而失宠。
    • 如果您担心 javac 中的错误,总会有 ecj。
    • @AlBlue,关于“编译器中的错误很少”的问题,是的,它们很少,但它们确实存在,我被它们咬了。为什么要为此烦恼?在图书馆不兼容的问题上,你完全错了——听起来你从来没有真正读过我的答案。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      我认为不会。

      有时(由于过于复杂的原因无法解释),我尝试在 1.6 JDK 中编译的 1.5 JRE 中运行代码。它通常会抛出 java.lang.UnsupportedClassVersionError 异常。

      【讨论】:

      • 这个答案激发了很大的信心。 ;)
      • 当然,您可以显式编译以实现如上所示的向后兼容性。
      【解决方案6】:

      是和不是。如果在编译时将“源”和“目标”javac 选项设置为目标版本(例如 1.4),则可以在 1.4 jvm 上运行在 Java 6 下编译的代码。这适用于您没有使用自目标版本以来添加的任何其他类或语言功能的情况。

      祝你好运。

      【讨论】:

        【解决方案7】:

        是的,您可以使用 1.6 编译器 (javac) 生成与 1.4 兼容的类文件,但是,仅仅这样做并不一定会生成可以工作的代码。问题是它仍然会针对 1.6 版本的 API 进行编译。

        乍一看你不会认为这是一个问题,因为合同不应该改变,但它是 - 我有一个问题,一个新的构造函数将 IIRC 一个整数添加到 BigDecimal(在 1.5 中)等等编译时指定了对该构造函数的调用,但是在运行时该构造函数不存在,因此出现运行时异常。当方法重载并且您依赖自动变量转换时,您可能会遇到这样的问题。

        Javac 应用实际上独立于它所属的 Java 版本 - 您可以指定一个不同的 API 来针对 1.6 javac 使用,并且为了避免任何运行时问题,应该这样做。

        【讨论】:

          【解决方案8】:

          Java 1.5 是一个主要版本,它引入了枚举、自动装箱和其他东西。编译时你会得到异常说不支持的类版本。但是如果你使用命令 javac -source 1.4 -target 1._ claasname.java 编译它将编译。

          如果您在该场景中使用 1.5 的功能,如自动装箱和枚举,则无法编译,因为这些功能在 1.4 中不可用。在这种情况下,我们需要根据一些工具将代码转换为旧版本。

          【讨论】:

            猜你喜欢
            • 2012-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-04-09
            • 2011-01-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多