不同的JDK更新是否会生成不同的Java字节代码?

假设情景:

我有一个项目的源合规级别指定为1.5。 现在我用两个不同的JDK编译这个项目:首先使用JDK 6 Update 7,然后使用JDK 6 Update 20。

这两个不同的JDK是否会生成不同的Java字节代码,尽管它们的Update版本只有不同?

生成的代码通常仅在编译器错误修复的情况下有所不同。

但是,JLS 没有指定从源代码到生成的字节代码的1:1映射,因此您不应该依赖于生成完全相同的字节代码。

没有什么可以阻止不同版本生成不同的字节码,只要它符合JLS中指定的行为即可 。 JLS留下了许多实现细节,从一个实现到另一个实现。

让我们从另一方面回答:不能保证任何两个版本的jdk产生相同的字节代码。 所以你可以期待一般的差异。

如果至少在某些情况下它没有导致更改字节代码,那么为什么地球上有人会遇到发布更新开发工具包的麻烦? 我强烈怀疑是否有人会为了文档更新而这样做。

字节码可能略有不同,但这不用担心,因为它仍然是兼容的。

真正要执行的是取决于JIT。

例如JDK 6 Update 7的编译器可能输出与JDK 6 Update 20的编译器略有不同的字节码,但由于它是Java 6,因此类文件将完全兼容 – 您将能够运行使用Update 20编译的代码更新7没有任何问题。

在主要Java版本(例如Java 5与Java 6)之间可能存在更改,因此在较新版本上编译的代码将无法在旧版本上运行。 例如,对于Java 7,很可能会出现一个新指令invokedynamic 。 包含该指令的类文件将无法在较旧的Java版本上运行。

但是,更新版本之间从未进行过如此大的更改。

正如通常用于不同的编译器一样,它也是在Java情况下:结果必须相同,但它的到达方式可以(从字节码的角度来看)不同,例如由于优化或类似。 JVM是基于堆栈的V机器; 以下是一个虚构的例子(我不知道jvm助记符的指令操作码)

 推10
推20
加 
 推19
推1
加
推10
加 

这些产生相同的结果,但生成的字节码是不同的(第一个稍微优化,第二个是“完全”未优化;第三个选项可能是push 30因为我们添加已知(可能在编译时)常量)。 这是一个简单的案例,但可以轻松构建更复杂的案例。

如果使用不同的JDK版本进行编译,我建议使用javac的target选项。 否则,您可能无法使用较旧的JDK运行jar。

您可能还想使用javac的source选项,以确保开发人员不使用在最近的JDK中添加的类/方法。