不同的 Java 编译器(供应商不同)会产生不同的字节码 [英] Do different Java Compilers (where the vendor is different) produce different bytecode

查看:28
本文介绍了不同的 Java 编译器(供应商不同)会产生不同的字节码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定相同的主要版本,比如 Java 7,不同的 Java 编译器(例如,Oracle 的热点、JRockit 或 IBM 的 J9 等)是否将给定的 Java 源代码文件编译为相同的字节码?

扫描 Java 7 语言规范似乎正在讨论的是语言的语义,而不是代码到字节码的转换.

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.

这个问题与给定供应商的不同主要.次要版本产生相同的字节码不同.这个问题已经在这里得到回答 - 带有 可能是.

This question is not the same as do different major.minor versions for a given vendor produce the same bytecode. That question is already answered here - with a could be.

从以下答案Java 类文件的创建是确定性的吗? 以及对该答案的评论,引用了 this 以及上面1和major.minor问题的两个答案2,我认为我的问题的答案是.

From the following answer to Is the creation of Java class files deterministic? 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.

以上内容摘录:

JLS 留下了许多实现细节,从一个实施到另一个.

The JLS leaves many implementation details to vary from one implementation to another.

然而,JLS 并未指定从源代码到生成的字节码,所以你不应该依赖完全相同的字节要生成的代码.

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.

还有一条评论这里有不同的含义:

Yet a comment here implies differently:

它是编译器,即 javac,使用一个等等等等等等.这与 HotSpot 无关.

It’s the compiler, i.e. javac, creating the code using a BLAH BLAH BLAH. This has nothing to do with HotSpot.

这意味着给定代码 X,所有 javac 实现(相同版本/不同供应商)必须生成相同的 Y 字节码.

It implies that given a code X all javac implementations (same version/different vendors) must produce the same Y bytecode.

我看不出这是怎么回事,但我无法验证它是否正确(或我认为,见上文)是正确的.

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.

能否给出明确的答案?

推荐答案

编译器之间存在差异,有趣的是,一些允许的差异导致了过去的问题.

There are differences between the compilers and interestingly some of the permitted differences led to problems in the past.

有些差异很小,例如一些编译器优化 x=x+1 以生成与 x++ 相同的字节码,其他编译器不会.

Some differences are small, e.g. some compilers optimize x=x+1 to produce the same bytecode as x++, others don’t.

其他人可能会产生更大的影响,例如标准没有具体说明如何生成合成成员的名称,过去用于实现内部类访问私有成员(以及类似的东西)(不知道今天是否如此).但是计算默认值的算法 serialVersionUID 对所有类成员使用哈希码,即使是合成成员.

Others can have more impact, e.g. 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.

因此,使用 javac 或第一个 Eclipse 版本编译会创建具有不兼容 serialVersionUID 的类.今天,Eclipse 对合成成员使用与 javac 相同的名称架构,并在默认情况下发出关于 Serializable 类中缺少显式 serialVersionUID 的警告.

As a consequence, compiling with javac or the first Eclipse versions created classes with incompatible serialVersionUIDs. Today, Eclipse uses the same name schema for synthetic members as javac and issues a warning about missing explicit serialVersionUIDs in Serializable classes by default.

仍然有很多自由,甚至用 pack200 打包和解包可能会创建与原始类不同字节码的类.

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.

这篇关于不同的 Java 编译器(供应商不同)会产生不同的字节码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆