javac生成的类文件是否始终相同?

时间:2012-03-29 15:16:18

标签: javac

目前我们正在为大型项目(大约2000个源文件)重新编写所有构建系统的脚本,并且已经谈到对文件进行二进制比较以确保一切正确,这导致以下问题: javac的输出是否保证在编辑中相同,还是可以更改?

Another question暗示常量池可能有不同的顺序,但假设我们能够控制进入javac调用的文件的顺序是否仍存在差异的可能性?我们正在使用Ant和Maven作为构建的一部分,如果它也可能影响事物。

3 个答案:

答案 0 :(得分:3)

字节码绝对保证是相同的;首先,允许编译器执行不影响任何保证行为的优化。 Java语言规范甚至在一些地方提到了编译器可能执行的优化;例如,在字符串连接运算符+中,它注意到:

  

实现可以选择在一个步骤中执行转换和连接,以避免创建然后丢弃中间String对象。为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似技术来减少通过表达式求值创建的中间String对象的数量。

[link]

答案 1 :(得分:0)

我不是编译器的专家,但我倾向于相信其他答案说二进制比较不是100%可靠。

我考虑另一种选择:您应该能够检查构建系统创建的工件(.jars& .wars等)并确保每个工件都具有预期的内容,甚至是每个文件的大小是在一个相当严格的容忍范围内。

如果您的构建脚本正在生成源代码并对其进行编译,那么您应该能够对生成的源进行比较,我希望从构建到构建将 100%稳定。 (或至少可以预测)。

希望这有帮助!

答案 2 :(得分:0)

确保等价的唯一方法是获取几个类文件解析器中的一个,解析文件,然后执行繁重的工作,找出由于常量池顺序更改等导致的差异。主要问题是重新排序常量pool将更改引用常量的数值,其中一些是表元素,其中一些是字节码。可行,但绝对不重要,并且可能不实用,除非您已经出于某些其他原因(例如字节码修改)已经拥有大部分框架。