当前位置: 首页 > 面试题库 >

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

轩辕弘雅
2023-03-14
问题内容

给定相同的主要版本,例如Java
7,不同的Javahtml" target="_blank">编译器(例如Oracle的热点,JRockit或IBM的J9等)是否将给定的Java源代码文件编译为相同的bytcode?

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

YES

以上摘录为:

JLS留下了许多实现细节,因一个实现而异。

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

但是,这里的注释含义不同:

它是编译器,即javac,使用BLAH BLAH BLAH创建代码。这与HotSpot无关。

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

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

可以给出明确的答案吗?


问题答案:

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

有些差异很小,例如,某些编译器进行了优化x=x+1以产生与相同的字节码x++,而其他则没有。

其他可能会产生更大的影响,例如,该标准未指定过去如何生成用于实现对私有成员(和类似事物)进行内部类访问的合成成员的名称(我不知道今天是否这样做)。但是,用于计算默认值的算法serialVersionUID在所有类成员(甚至是合成成员)上都使用了哈希码。

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

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



 类似资料:
  • 现在,我有下面的代码,它只是测试标准库中的< code>std::set_difference: 当我用Clang/GCC编译它时,我得到了输出: 更新我想实际使用的源代码案例(假设是我将要做的一些操作。因此,这些操作将按的顺序发生): 好吧,这看起来不错,它实际上对应于标准::set_difference,检查链接:但是当我选择MSVC时,我得到了不同的输出(检查链接:https://godbo

  • 考虑下面这个简短的C++程序: 如果我在不同的编译器上编译它,我会得到不同的结果。对于CLANG3.4和GCC 4.4.7,它打印,而Visual Studio 2013打印,这意味着它们在调用不同的强制转换操作符。根据标准,哪一个是正确的行为? 根据我的理解,不需要转换,而需要到的转换,因此编译器应该选择第一个。对此做了什么吗?const-conversion是否被编译器认为更“昂贵”? 如果删

  • 上面的代码使用不同的编译器会有不同的结果。这是编译器的错误还是我漏掉了什么? 叮叮当当 1 1 (https://godbolt.org/z/s43T55rxq) msvc 1 1 (https://godbolt.org/z/YnKfKh41q) 全球循环 0 1 (https://godbolt.org/z/91xdfv93c)

  • 使用Java的hashcode函数可以为不同的字符串提供相同的hashcode吗?或者如果有可能,那么可能性的百分比是多少?

  • 问题内容: 我正在尝试比较以下结果:(在蚂蚁中) ……对此:(在行家中) …只是发现生成的两个类文件的校验和略有不同,而其余的相同。我认为多线程起了一定的作用,但是在反复尝试后,为这两个选项生成的校验和似乎是一致的。什么可能解释这个结果? 更新: 我使用来检查了一组具有不同校验和的文件,并注意到唯一的区别是: 相对于: 问题答案: 如您所展示的,差异在于生成的常量池,这实际上不是问题,但是令人不安

  • 相同版本的代码优化是否有任何差异:OracleJava编译器ApacheJava编译器IBMJava编译器OpenJDKJava编译器。如果有什么代码可以展示不同的优化?或者他们使用相同的编译器?如果没有已知的优化差异,那么我在哪里可以找到关于如何测试不同优化的编译器的资源?