是Java类文件的创建是确定性的吗? [英] Is the creation of Java class files deterministic?

查看:132
本文介绍了是Java类文件的创建是确定性的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用相同的JDK (即相同的 javac 可执行档)时,生成的类文件是否始终相同?根据操作系统硬件,可能会有差异吗?除了JDK版本,可能有任何其他因素导致差异吗?有没有任何编译器选项,以避免差异?是不是只有可能在理论上或者Oracle的 javac 实际上为相同的输入和编译器选项产生不同的类文件?



更新1 我对生成感兴趣,即编译器输出,而不是类文件是否可以在各种平台上运行。



更新2 通过相同的JDK,我也意味着相同的 javac 可执行文件。



更新3 在Oracle的编译器中区分理论差异和实际差异。





在不同的平台上运行相同的javac可执行文件时,会产生不同的字节码?

解决方案

让我们用这种方式:



一个完全符合的Java编译器,从不产生相同的 .class 文件两次,给定相同的 .java 文件。 p>

我可以通过调整各种字节码构造或者简单地添加多余的属性到我的方法(这是允许的)。



由于 不需要编译器产生逐字节相同的类文件,因此我会避免依赖这样的结果。



然而,,几次,我检查,编译同一源文件与相同的编译器与相同的开关(和相同的库!)会产生相同的 .class 文件。



更新:我最近偶然发现了这个有趣的博文,介绍了 switch on String 。在这篇博文中,有一些相关的部分,我会在这里引用(强调我的):


输出可预测和可重复,在这些数据结构中使用的映射和集合 LinkedHashMap s和 LinkedHashSet code> HashMaps 和 HashSets 在给定编译期间的函数正确性方面使用 HashMap HashSet 会很好;迭代顺序无关紧要。然而,我们发现 javac 的输出不会根据系统类的实现细节而变化。

$


这非常清楚地说明了这个问题:编译器不需要以确定的方式操作,只要它符合规范。然而,编译器开发人员意识到,一般来说, 是一个好主意 (假设它可能不太贵)。


When using the same JDK (i.e. the same javac executable), are the generated class files always identical? Can there be a difference depending on the operating system or hardware? Except of the JDK version, could there be any other factors resulting in differences? Are there any compiler options to avoid differences? Is a difference only possibly in theory or does Oracle's javac actually produce different class files for the same input and compiler options?

Update 1 I'm interested in the generation, i.e. compiler output, not whether a class file can be run on various platforms.

Update 2 By 'Same JDK', I also mean the same javac executable.

Update 3 Distinction between theoretical difference and practical difference in Oracle's compilers.

[EDIT, adding paraphrased question]
"What are the circumstances where the same javac executable,when run on a different platform, will produce different bytecode?"

解决方案

Let's put it this way:

I can easily produce an entirely conforming Java compiler that never produces the same .class file twice, given the same .java file.

I could do this by tweaking all kinds of bytecode construction or by simply adding superfluous attributes to my method (which is allowed).

Given that the specification does not require the compiler to produce byte-for-byte identical class files, I'd avoid depending such a result.

However, the few times that I've checked, compiling the same source file with the same compiler with the same switches (and the same libraries!) did result in the same .class files.

Update: I've recently stumbled over this interesting blog post about the implementation of switch on String in Java 7. In this blog post, there are some relevant parts, that I'll quote here (emphasis mine):

In order to make the compiler's output predictable and repeatable, the maps and sets used in these data structures are LinkedHashMaps and LinkedHashSets rather than just HashMaps and HashSets. In terms of functional correctness of code generated during a given compile, using HashMap and HashSet would be fine; the iteration order does not matter. However, we find it beneficial to have javac's output not vary based on implementation details of system classes .

This pretty clearly illustrates the issue: The compiler is not required to act in a deterministic manner, as long as it matches the spec. The compiler developers, however, realize that it's generally a good idea to try (provided it's not too expensive, probably).

这篇关于是Java类文件的创建是确定性的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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