Is the class file generated by javac always the same?

两盒软妹~` 提交于 2020-01-02 03:31:11

问题


Currently we are in the process of re-scripting all of our build system for a large project (around 2000 source files) and there has been talk of doing a binary comparison on the files to ensure that everything is correct which leads to the following question: Is the output of javac guaranteed to be same across compilations or could it be subject to change?

Another question implied that the constant pool could have a different order, but assuming we are able to control for the order of the files going into the javac call is there still a potential for differences? We are using Ant and Maven as part of the build if that may influence things as well.


回答1:


The bytecode is absolutely not guaranteed to be the same; for one thing, compilers are allowed to perform optimizations that don't affect any guaranteed behaviors. The Java Language Specification even mentions, in a few places, optimizations that a compiler might perform; for example, of the string concatenation operator +, it notes that:

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

[link]




回答2:


I am not an expert on the compiler, but I tend to believe the other answers saying that binary comparison is not 100% reliable.

I'd consider another alternative: You should be able to inspect the artifacts your build system creates (.jars & .wars, etc.) and ensure that each have the expected contents, and even that the size of each file is within a fairly tight tolerance.

If your build script is generating source and compiling it, then you should be able to do comparisons against the generated source, which I expect would be 100% stable from build to build. (Or at least predictable).

Hope this helps!




回答3:


The only way to assure equivalence is to get one of the several class file parsers, parse the files, then do the heavy work of figuring out differences due to constant pool order changes, etc. The main problem is that reordering the constant pool will change numeric values that reference the constants, some of which are in table elements, some of which are in bytecodes. Doable, but definitely non-trivial, and probably not practical unless you already have most of the framework in place for some other reason (such as bytecode modification).



来源:https://stackoverflow.com/questions/9928330/is-the-class-file-generated-by-javac-always-the-same

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!