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

时间:2010-06-10 08:59:48

标签: compiler-construction compilation java

假设情景:

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

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

8 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:9)

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

真正执行的内容取决于JIT。

答案 5 :(得分:1)

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

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

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

答案 6 :(得分:0)

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

push 10
push 20
add
push 19
push 1
add
push 10
add

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

答案 7 :(得分:0)

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

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