简体   繁体   English

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

[英]Do different JDK Updates produce different Java byte code?

A hypothetical scenario: 假设情景:

I've got a project whose source compliance level is specified to 1.5. 我有一个项目的源合规级别指定为1.5。 Now I compile this project with two different JDKs: At first with JDK 6 Update 7 and then with JDK 6 Update 20. 现在我用两个不同的JDK编译这个项目:首先使用JDK 6 Update 7,然后使用JDK 6 Update 20。

Do these two different JDKs produce different Java byte code, although they only differ in their Update version? 这两个不同的JDK是否会生成不同的Java字节代码,尽管它们的Update版本只有不同?

There is nothing that would stop the different versions from generating different bytecodes, as long as it's compliant to the behavior specified in the JLS. 没有什么可以阻止不同版本生成不同的字节码,只要它符合JLS中指定的行为即可 The JLS leaves many implementation details to vary from one implementation to another. JLS留下了许多实现细节,从一个实现到另一个实现。

The generated code usually only differs in case of compiler bug fixes. 生成的代码通常仅在编译器错误修复的情况下有所不同。

However the JLS does not specify a 1:1 mapping from source code to the generated byte code, so you should not rely on the exact same byte code to be generated. 但是,JLS 没有指定从源代码到生成的字节代码的1:1映射,因此您不应该依赖于生成完全相同的字节代码。

Let's answer it from the other side: there is no guarantee that any two versions of the jdk produce the identical byte code. 让我们从另一方面回答:无法保证任何两个版本的jdk产生相同的字节代码。 So you can expect differences in general. 所以你可以期待一般的差异。

Why on Earth would someone go to the trouble of issuing an Update of a development kit if it didn't lead to changed byte code in at least some cases? 如果至少在某些情况下它没有导致更改字节代码,那么为什么在地球上有人会遇到发布更新开发工具包的麻烦? I strongly doubt anyone would do it just for documentation updates. 我强烈怀疑是否有人会为了文档更新而这样做。

The bytecode could slightly differ, but this is nothing to worry about since it will be still compatible. 字节码可能略有不同,但这不用担心,因为它仍然是兼容的。

What really will be executed depends on JIT. 真正要执行的是取决于JIT。

The compiler of for example JDK 6 Update 7 might output slightly different bytecode than the compiler of JDK 6 Update 20, but since it's both Java 6, the class files will be fully compatible - you will be able to run code compiled with Update 20 on Update 7 without any problems. 例如JDK 6 Update 7的编译器可能输出与JDK 6 Update 20的编译器略有不同的字节码,但由于它是Java 6,因此类文件将完全兼容 - 您将能够运行使用Update 20编译的代码更新7没有任何问题。

Between major Java versions (for example Java 5 vs. Java 6) there might be changes so that code compiled on the newer version will not run on the older version. 在主要Java版本(例如Java 5与Java 6)之间可能存在更改,因此在较新版本上编译的代码将无法在旧版本上运行。 For example, for Java 7 there is most likely going to be a new instruction, invokedynamic . 例如,对于Java 7,很可能会出现一个新指令invokedynamic Class files that contain that instruction will not be runnable on older Java versions. 包含该指令的类文件将无法在较旧的Java版本上运行。

Such large changes are however never done between update versions. 但是,更新版本之间从未进行过如此大的更改。

As usually is for different compilers, it is also in the Java case: the result must be the same but the way it is reached can be (from the bytecodes point of view) different., eg because of optimizations or alike. 正如通常用于不同的编译器一样,它也是在Java情况下:结果必须相同,但它的到达方式可以(从字节码的角度来看)不同,例如由于优化或类似。 The JVM is stack based V machine; JVM是基于堆栈的V机器; the following is an imaginary example (I don't know jvm mnemonics for the instructions opcodes) 以下是一个虚构的例子(我不知道jvm助记符的指令操作码)

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

These produce same result, but generated bytecodes are different (the first is slightly optimized, the second is "totally" not optimized; a third option could be push 30 since we are adding known (likely at compiletime) constants). 这些产生相同的结果,但生成的字节码是不同的(第一个稍微优化,第二个是“完全”未优化;第三个选项可能是push 30因为我们添加已知(可能在编译时)常量)。 This is a simple case, but more complex case can be easily built. 这是一个简单的案例,但可以轻松构建更复杂的案例。

If you compile with different JDK versions I would advice to use the target option to javac. 如果使用不同的JDK版本进行编译,我建议使用javac的target选项。 Otherwise you may not be able to run the jar with an older JDK. 否则,您可能无法使用较旧的JDK运行jar。

You may also want to use the source option to javac, in order to make sure the developer do not use classes/methods added in a more recent JDK. 您可能还想使用javac的source选项,以确保开发人员不使用在最近的JDK中添加的类/方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不同的Java编译器(供应商不同)会产生不同的字节码 - Do different Java Compilers (where the vendor is different) produce different bytecode 为什么不同的Java反编译器显示不同的源代码? - Why different Java de-compilers show different source code? 字节码在java中有什么用 - What is the use of Byte code in java Java编译器对象代码(字节代码?) - Java Compiler Object Code (Byte Code?) 为什么Sun不用C#来编写Java字节码编译器? - Why doesn't Sun do a C# to Java byte code compiler? 在 java 代码中,我如何检查 jdk 版本以在 java 代码下编译? - At java code, how i can check jdk version to compile below java code? Java编译器是否针对不同的语言环境进行翻译? - Are Java compilers translated for different locales? 为什么同一段(简单的)Java代码在不同的Android设备上的行为会大不相同? - Why same piece of (simple) Java code behaves very differently on different Android devices? 在Java中,对BaseClass的更改会影响SubClass的字节码吗? - In Java does changes to the BaseClass effect the byte code of the SubClass? 同一个 javac 编译器是否可以编译相同的源文件集但生成不同校验和的类文件? - Is it possible for the same javac compiler to compile the same set of source files but produce class files of different checksums?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM