简体   繁体   English

不同的Java编译器(供应商不同)会产生不同的字节码

[英]Do different Java Compilers (where the vendor is different) produce different bytecode

Given the same major version, say Java 7, do different Java Compilers (eg, Oracle's hotspot, JRockit, or IBM's J9 etc...) compile a given java source code file into the same bytcode? 给定相同的主要版本,比如Java 7,做不同的Java编译器(例如,Oracle的热点,JRockit或IBM的J9等......)将给定的java源代码文件编译成相同的bytcode?

Scanning the Java 7 language spec it would seem that what is being discussed is the semantics of the language and not the transformation of the code into bytecode. 扫描Java 7语言规范似乎正在讨论的是语言的语义,而不是将代码转换为字节码。

This question is not the same as do different major.minor versions for a given vendor produce the same bytecode. 这个问题与不同的major.minor版本不同,给定供应商生成相同的字节码。 That question is already answered here - with a could be . 这个问题已在这里得到解答 - 可能是

From the following answer to Is the creation of Java class files deterministic? 从以下答案Java类文件的创建是否确定? and a comment to that answer that refers to this along side two answers to the major.minor question above 1 and 2 , I gather that the answer to my question is YES . 和这个问题的答案是指评论沿侧两个答案上述问题MAJOR.MINOR 12 ,我收集了答案,我的问题是YES。

Excerpts for the above are: 上述摘录如下:

The JLS leaves many implementation details to vary from one implementation to another. JLS留下了许多实现细节,从一个实现到另一个实现。

and

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映射,因此您不应该依赖于生成完全相同的字节代码。

Yet a comment here implies differently: 然而, 这里的评论意味着不同:

It's the compiler, ie javac, creating the code using a BLAH BLAH BLAH. 它是编译器,即javac,使用BLAH BLAH BLAH创建代码。 This has nothing to do with HotSpot. 这与HotSpot无关。

It implies that given a code X all javac implementations (same version/different vendors) must produce the same Y bytecode. 这意味着给定代码X所有javac实现(相同版本/不同供应商)必须生成相同的Y字节码。

I cannot see how that is so, but I am unable to verify that it is not (or that what I think, see above) is correct. 我不明白这是怎么回事,但我无法证实它不是(或者我认为,见上文)是正确的。

Can a definitive answer be given? 可以给出明确的答案吗?

There are 2 questions: 有两个问题:

  1. Are different java compilers free to generate different bytecode for the same sourrce code? 不同的java编译器是否可以为相同的源代码生成不同的字节码?
  2. Do they actually produce different bytecode for the same source. 它们实际上是否为同一源生成不同的字节码。

The answer to 1 is yes, obviously. 显然,1的答案是肯定的。 For, otherwise, the JLS had to fully specify the bytecode to generate for each and every language construct. 否则,JLS必须完全指定为每个语言结构生成的字节码。 But it doesn't. 但事实并非如此。

The answer to 2 I don't know for sure, though I have heard that eclipse compiler generates slightly different code than javac in some cases. 2的答案我不确定,虽然我听说eclipse编译器在某些情况下产生的代码与javac略有不同。 Should be easy to verify. 应该很容易验证。

The comment in question does not actually disagree. 有问题的评论实际上并不反对。 Note that you are mixing up two different things here: Java bytecode compilers ( javac ) and Java just-in-time compilers (such as HotSpot or J9). 请注意,您在这里混合了两个不同的东西:Java字节码编译器( javac )和Java即时编译器(例如HotSpot或J9)。 You normally use some javac implementation to translate java source code to java bytecode. 您通常使用一些javac实现将java源代码转换为java字节码。

Then you take the bytecode and execute it in a JVM, which uses another compiler. 然后你获取字节码并在JVM中执行它,它使用另一个编译器。

Again, there are two sets of compilers: 同样,有两组编译器:

  1. Bytecode compilers ( .java to .class ) 字节码编译器( .java.class
  2. Just-in-time compilers as part of Java virtual machines (execute .class files) 即时编译器作为Java虚拟机的一部分(执行.class文件)

( EDIT: Neither of these are guaranteed to produce identical results (ie, the same java file can yield different class files, and the same class file can yield different machine code when the JIT is done with it.)) 编辑:这些都不能保证产生相同的结果(即,相同的java文件可以产生不同的class文件,并且当JIT完成时,相同的class文件可以产生不同的机器代码。))

The reason for having two sequential compilation processes is that if you wrap everything into one compiler, you lose two properties: 有两个顺序编译过程的原因是,如果将所有内容都包装到一个编译器中,则会丢失两个属性:

  1. your compiled program will be platform-specific 您编译的程序将是特定于平台的
  2. your program will not (easily) be able to perform some of the optimisations and advanced language features (reflection, dynamic class loading) that Java provides. 您的程序将不会(轻松地)执行Java提供的一些优化和高级语言功能(反射,动态类加载)。

There are differences between the compilers and interestingly some of the permitted differences led to problems in the past. 编译器之间存在差异,有趣的是,一些允许的差异导致了过去的问题。

Some differences are small, eg some compilers optimize x=x+1 to produce the same bytecode as x++ , others don't. 一些差异很小,例如,一些编译器优化x=x+1以产生与x++相同的字节码,而其他编译器则不然。

Others can have more impact, eg the standard did not specify how to generate the names of synthetic members used to implement inner class access to private members (and similar things) in the past (I don't know whether it does today). 其他人可能会产生更大的影响,例如标准没有指定如何生成过去用于实现私有成员(和类似事物)的内部类访问的合成成员的名称(我不知道它是否在今天)。 But the algorithm for calculating a default serialVersionUID used a hash code over all class members, even synthetic ones. 但是用于计算默认serialVersionUID的算法在所有类成员上使用哈希码,甚至是合成成员。

As a consequence, compiling with javac or the first Eclipse versions created classes with incompatible serialVersionUID s. 因此,使用javac或第一个Eclipse版本进行编译会创建具有不兼容的serialVersionUID的类。 Today, Eclipse uses the same name schema for synthetic members as javac and issues a warning about missing explicit serialVersionUID s in Serializable classes by default. 今天,Eclipse对合成成员使用与javac相同的名称模式,并在默认情况下发出有关在Serializable类中缺少显式serialVersionUID的警告。

There's still a lot of freedom and even packing with pack200 and unpacking may create classes with different byte code than the original classes. 仍然有很多自由,甚至包装pack200包可能会创建具有不同于原始类的字节代码的类。

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

相关问题 Linux和Windows java编译器是否生成相同或不同的类文件? - Do Linux and Windows java compilers produce the same or different class files? java字节码的不同行为 - Different behaviour of java bytecode Java编译器是否针对不同的语言环境进行翻译? - Are Java compilers translated for different locales? 不同的JDK更新是否会生成不同的Java字节代码? - Do different JDK Updates produce different Java byte code? IDE和编译器的/ t间距是否不同? (IntelliJ上的JAVA) - Do IDEs and compilers have different spacing for /t spacing? (JAVA on IntelliJ) Java字节码是否与不同版本的Java兼容? - Is Java bytecode compatible with different versions of Java? 具有不同种子的Java Random实例确实会产生不同的序列,还是它们以相同的序列在不同的地方开始? - Do Java Random instances with different seeds really produce different sequences, or do they start at different places in the same sequence? Java 字节码:在具有不同类的对象引用上调用虚拟方法引用 - Java Bytecode: invokevirtual methodref on an objectref with a different class 为什么不同的Java反编译器显示不同的源代码? - Why different Java de-compilers show different source code? Java字节码是否与同一版本的Java的不同更新兼容? - Is Java bytecode compatible within different updates of the same version of Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM