为什么编译 java 不向前兼容

Why is compiled java not forwards compatible

除非我误解了 JVM 的工作方式,否则 Java 字节码在某种程度上与编译的 C 一样,只是它 运行 在 JVM 上而不是 OS(JVM 充当 OS)?

如果是这样,这是否意味着较新的 ​​jar 应该能够 运行 在我想要的任何版本的 JVM 上?

或者 Java 版本之间的实际字节码指令是否存在某种差异,而 C 等版本不存在?

没有。通常会引入实际的(不兼容的)差异来支持新功能(并且 总是 版本号)。字节码是向后兼容的,因为旧编译器编译的字节码可以被 newer 环境(向后)调用(和链接)。它与 forwards 不兼容,这正是您实际询问的内容。无论如何,您可以使用 javap -v 检查指令助记符并查看版本。

此外,根据您的问题,(作为 设计的 示例)使用 gcc 编译的代码以针对具有 -march=586 的英特尔奔腾处理器(可能)获胜't 运行 在 486386 上(与 -mtune 相反)。

它不向前兼容,因为这意味着不可能引入新的 byte-codes。

当 java 的新版本引入新的字节码时,旧版本的 VM 自然无法解释该字节码。

这意味着 java 无法向前兼容,因为它维护了一组不断发展的(本机)命令。

这与 C/C++ 不同。这种语言的编译器为 确切的处理器 生成 byte-code 您的目标。处理器的命令集不会改变,它是静态的。因此,当为特定 CPU 编译 C 时,C/C++ 标准的每个版本都将编译和 运行,只要有对应于所需操作的指令。


编辑:当你仔细观察时,这个问题也可以在 C/C++ 中看到。例如 header <cstdint> 引入了 optional 类型,例如int64_t。这是出于向前兼容性的原因。较旧的芯片可能无法处理 64 位整数类型,因此为了保持它们的前向兼容性,标准使它们可选择声明。