较新的JRE版本能否运行用较旧的JDK版本编译的Java程序?

97

我用Java 1.7编译程序,但有些库是用Java 1.6编译的。在1.7 JRE中运行整个程序是否会遇到问题?

您在使用Java 1.7编译程序时,包含的一些库是使用Java 1.6编译的,这可能会导致兼容性问题。但如果您将整个程序在1.7 JRE中运行,则不太可能出现任何重大问题。建议您测试一下程序并确认是否按预期工作。
2个回答

111

如已回答,您大多数情况下是安全的,大多数产品和第三方库都可以正常工作。然而,存在(不太)罕见的二进制不兼容性

这些不兼容性发生在使用旧JDK编译的类无法在新JVM中运行,因为在使用JDK编写和编译代码之后,JDK本身引入了破坏兼容性的更改(例如类删除类/方法可见性降低方法签名更改包更改)。

对于Java 9及更早版本:
Oracle Java不兼容性的官方列表:

针对Java 9及以上版本:
兼容性工具

随着JDK 9及以后版本的发布,附带了jdeprscan工具,该工具可以验证兼容性,列出您代码中不再使用的API并提供替代方案(!)。您可以指定目标JDK版本(适用于JDK 17119876),它将列出特定于您目标版本的不兼容性。

关于库的额外说明:

一个合理的经验法则是为软件目标的JRE版本使用最新的稳定版本库。显然,您会发现许多例外情况,但总体而言,公开可用库的稳定性通常会随时间增加。

当更改依赖项的版本时,自然需要考虑API兼容性版本控制

同样,大多数流行的依赖项都将有网页,其中应该提供此类信息。

如果您使用的是一些更为冷门的东西,您可以确定依赖项内的类是为哪个JRE编译的。 这里有一个很好的答案,告诉您如何查找类版本。您可能需要先解压JAR文件。

12
实际上,这应该是正确的答案,因为升级到更高版本的Java并不完全安全。 - dehlen
如果不使用任何jdk8功能,编译1.8并以1.8为目标,那么它能正常工作吗? - Gaurav
不清楚“since”是什么意思。在Java SE 9中,“since Java SE 8”是否意味着Java 8编译的Java程序在9上无法运行?那么在9之后呢? - Mark Deven
1
从Java 9开始,标准库中有很多旧的无用内容被删除了。依赖这些类的代码将不再起作用,除非将提供这些类的外部依赖项引入类路径中。当这样做时,它应该再次起作用(请注意,其中一些类没有外部等价物,但这些类也永远不应该直接使用,并且始终带有相应的警告)。 - jwenting

100

*** 更新 ***

自2020年左右起,以下答案不再准确。在过去的十年里,Java发生了如此多的变化,兼容性被牺牲以推动事物向前发展。

尽管大部分代码和知识都可以转移到较新的版本,但现在有很多例外情况。然而,在我的经验中,迁移有时可能相当容易。

*** 更新结束 ***

你不会遇到任何问题 - 这就是Java的魔力 - 它是向后兼容的。你可以在Java 8上运行几乎所有Java 1的代码。 Java6的代码在Java 8运行时上也没有问题。

有趣的是,对于使用Java 1.4编写的应用程序,即使在后来的运行时上运行它们,速度也有所提升。这是因为Java不断发展,不仅是被称为“Java”的语言,还有JVM(Java虚拟机)。我仍然拥有10多年前的源代码,它们在最新的JVM中仍然正常工作。

如果你想要针对 Java 5 虚拟机进行开发,那么你可以使用 Java 8 SDK 工具来实现。只要你记住版本 5 的虚拟机可能不支持版本 8 的所有功能,你就可以指定你希望支持的目标虚拟机。

我刚刚测试了我在 Java 5 中编写的代码,并在新的 Java 8 运行时中运行,一切都如预期般工作。因此,即使我们现在拥有更强大的语言和运行时,我们仍然可以继续使用过去的投资。这使得 Java 成为公司的一个很好的开发选择。


2
如果您在Java 7运行时中运行它,是的。没有理由它不能工作。 - Ewald
1
如果您使用JDK 7进行开发,并将应用程序编译为JDK 7应用程序,那么它将无法在旧的运行时上运行。有许多理由要求用户请升级到最新的运行时,主要是出于安全原因,但也涉及一些性能问题。 如果可以的话,我会选择Java 7,除非您确实必须支持旧版本,否则很少有必要。 - Ewald
1
-1 MagicDraw在更新的Java版本上无法运行,即使公司制作了降级教程http://www.nomagic.com/files/Java%20downgrade%20tutorial.pdf。 - NeDark
3
你看到了关于“你可以在Java 8上运行几乎所有来自Java 1的代码”的那一部分吗?尽管JVM的一些深奥部分存在一些小的不兼容性,但总体而言,Java仍然非常向后兼容。 - Ewald
6
大约8年后,很遗憾,这一点已不再成立。我正在遇到许多Java14和旧的Java应用程序方面的问题,因为它们依赖于现在已从Java Runtime中删除的功能。对于标准代码,是的,它仍然有效,但是有一些企业库您不能再依赖其存在。JavaFX也是如此。可惜这迫使我们的工作转向使用Rust,而不是Java。 - Ewald
显示剩余7条评论

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