哪些设置会影响已编译java.class文件的布局?如何判断两个编译类是否相等?

哪些设置会影响已编译java.class文件的布局?如何判断两个编译类是否相等?,java,compiler-construction,comparison,bytecode,javac,Java,Compiler Construction,Comparison,Bytecode,Javac,我有一个应用程序是用内置的Eclipse“Compile”任务编译的。然后我决定将构建过程移动到Ant的javac,结果是生成了更小的文件 后来我发现,将debuglevel调整为“vars,lines,source”可以嵌入与Eclipse相同的调试信息,并且在很多情况下,文件保持完全相同的大小,但内部布局不同。因此,我无法使用md5sum签名来确定它们是否是完全相同的版本 除了调试信息外,2个假定相等的文件获得不同内部布局或大小的原因是什么 如何比较编译后的.class文件?最重要的是,局部

我有一个应用程序是用内置的Eclipse“Compile”任务编译的。然后我决定将构建过程移动到Ant的
javac
,结果是生成了更小的文件

后来我发现,将debuglevel调整为
“vars,lines,source”
可以嵌入与Eclipse相同的调试信息,并且在很多情况下,文件保持完全相同的大小,但内部布局不同。因此,我无法使用md5sum签名来确定它们是否是完全相同的版本

除了调试信息外,2个假定相等的文件获得不同内部布局或大小的原因是什么


如何比较编译后的.class文件?

最重要的是,局部变量的堆栈槽可以任意排列,而无需更改代码的语义。因此,基本上,如果不对编译的类文件进行解析和规范化,就无法对它们进行比较——这是相当大的工作量


无论如何,您为什么要这样做?

Eclipse是否正在进行一些检测以帮助在调试器中运行?

最终,所使用的配置可能会产生影响。假设它们使用的是相同版本的Java,那么编译配置中有许多选项可用(JDK符合性、类文件兼容性和大量调试信息选项)。

对于常量池条目(基本上是所有符号信息)的顺序等事项,没有必要的顺序以及每个字段/方法/类的属性。不同的编译器可以自由地按照他们想要的顺序写出来


可以比较编译后的类,但需要深入研究类文件结构并对其进行解析。有很多库可以这样做,比如or,但我不能100%肯定它们会帮你做你想做的事情。

正如Michale B所说,这可能是任意的

我在使用文件大小作为安全性的系统上工作。如果.class文件的大小发生变化,则该类将不会被授予某些权限

通常这很容易做到,但我们对环境有相当完全的控制,所以它实际上非常实用

不管怎样,任何时候重新编译被监视的类,我们似乎都必须重新计算大小

另一件事——编译文件时会生成一个特殊的密钥号。我不太了解这一点,但它经常会阻止类一起工作。我相信这个过程是,编译类A并保存它(称为a1)。再次编译类a(a2)。针对类a2编译类b。试着在a1上运行b。我相信在这种情况下,它将在运行时失败


如果您可以了解有关该密钥号的更多信息,它可能会为您提供所需的信息。

对于比较,您可以反编译类文件并使用生成的源代码。请参阅。

ASM Eclipse中有一个字节码比较器。选择两个类,单击鼠标右键,然后进行字节码比较

需要注意的一点是Eclipse不使用javac。Eclipse有自己的编译器,因此生成的.class文件中的差异并不让我感到惊讶。我希望它们不会一字不差,因为它们是不同的编译器


由于它们的不同,存在使用javac而不是JDT编译的代码,反之亦然。通常情况下,我看到在大量使用仿制药的情况下,两者之间的差异变得明显

我不确定它是否在这样做。我怎么能证实呢?很有趣。只是出于好奇,为了学习。我知道这是我不应该真正依赖的东西。