Java 8 JVM-编译后字节码内容的差异

Java 8 JVM-编译后字节码内容的差异,java-8,jvm,winmerge,Java 8,Jvm,Winmerge,我最近看到了一种行为,这使我如此问这个问题。我希望人们也能分享他们的发现 如果使用JDK1.8U66和JDK1.8U121编译(未更改)同一个文件,那么类文件(字节码)会有所不同吗?我的意思是: 1) 我使用JDK1.8U66编译了一个应用程序 2) 我对1或2个文件进行更改,并使用JDK1.8U66重新编译 我能期望一些未更改的类文件具有不同的二进制内容,即使它们没有更改吗 我的理由是,当我对一个文件进行散列时,上面的步骤并没有改变——它们在磁盘上的大小相同,但散列代码完全不同。我使用Winm

我最近看到了一种行为,这使我如此问这个问题。我希望人们也能分享他们的发现

如果使用JDK1.8U66和JDK1.8U121编译(未更改)同一个文件,那么类文件(字节码)会有所不同吗?我的意思是:

1) 我使用JDK1.8U66编译了一个应用程序 2) 我对1或2个文件进行更改,并使用JDK1.8U66重新编译

我能期望一些未更改的类文件具有不同的二进制内容,即使它们没有更改吗

我的理由是,当我对一个文件进行散列时,上面的步骤并没有改变——它们在磁盘上的大小相同,但散列代码完全不同。我使用Winmerge来比较这两个版本,其中大小报告为相同,但二进制内容不同。下面是我使用Winmerge进行的比较(蓝色标记的项与我的源名称有关,因此我不得不将其屏蔽掉),但请注意208和248中的差异

这是预期的吗?如果是这样的话,有人能给我指一下解释这一点的文献吗


关于,

存在无数的原因,为什么同一个Java源文件可能被不同的编译器编译成不同的字节,而同一个编译器的不同版本确实应该被视为不同的编译器。即使对于完全相同的编译器,也不能保证字节是相同的

其中一个原因是,代码中的所有引用(操作码和字节码偏移量除外)都是通过。常量池中条目的顺序未指定,因此它可能会更改,从而导致使用不同偏移量的所有引用

另请参见JVM有一个标题为的部分,但是,它的开头是:

本章中编号的章节不具有规范性

因此,推理只能在一个方向上起作用:相同的字节意味着相同的源代码,但不同的字节并不一定意味着不同的源代码


,从一条注释链接而来,给出了一个示例,其中即使是同一个编译器也可以为同一个源文件生成不同的字节(可能是由于在同一个编译器调用中编译的源文件集不同)。根据JLS和JVM,这是合法的,只是不方便。

存在无数的原因,为什么同一个Java源文件可能被不同的编译器编译成不同的字节,而同一个编译器的不同版本确实应该被视为不同的编译器。即使对于完全相同的编译器,也不能保证字节是相同的

其中一个原因是,代码中的所有引用(操作码和字节码偏移量除外)都是通过。常量池中条目的顺序未指定,因此它可能会更改,从而导致使用不同偏移量的所有引用

另请参见JVM有一个标题为的部分,但是,它的开头是:

本章中编号的章节不具有规范性

因此,推理只能在一个方向上起作用:相同的字节意味着相同的源代码,但不同的字节并不一定意味着不同的源代码



,从一条注释链接而来,给出了一个示例,其中即使是同一个编译器也可以为同一个源文件生成不同的字节(可能是由于在同一个编译器调用中编译的源文件集不同)。根据JLS和JVM的说法,这是合法的,只是不方便。

您是否比较字节码以找出它们的不同之处?是的,我比较了,它们在方法参数名称上的不同之处,代码中的代码是208而不是248。这是唯一的区别只有一个字节改变了?不过,我真的不知道你所说的方法参数名是什么意思。@Bubleta用屏幕截图更新了这个问题。这个问题可能是由不稳定的lambda方法名引起的,请看你是否比较了字节码以找出它们的不同之处?是的,它们在方法参数名称上有所不同,其中代码中的代码是208而不是248。这是唯一的区别只有一个字节改变了?不过,我真的不知道你所说的方法参数名是什么意思。@Bubleta用截图更新了这个问题。这个问题可能是由不稳定的lambda方法名引起的,请参阅@StephanHermann Thank-不过,我倾向于JDK jira,因为它清楚地说这个问题是针对JDK9解决的。所以只要是JDK8,我就会有问题。@ha9u63ar,你可能是对的,但我的观点是:即使问题解决了,也不能保证字节码相等。@StephenHerrmann我不理解。但是,如果JDK是相同的,并且如果我连续编译同一个类5次而不更改任何字节,那么如果lambda不存在,那么它们应该是相同的,这样说是否仍然是错误的?或者这是错误的?@ha9u63ar编译器规范中没有这方面的要求,正如Stephan引用JVM指出的那样。另请参见“”和“”。@StephanHermann谢谢-不过,我倾向于JDK jira,因为它明确指出问题已针对JDK9解决。所以只要是JDK8,我就会有问题。@ha9u63ar,你可能是对的,但我的观点是:即使问题解决了,也不能保证字节码相等。@StephenHerrmann我不理解。但是,如果JDK是相同的,并且如果我连续编译同一个类5次而不更改任何字节,那么如果lambda不存在,那么它们应该是相同的,这样说是否仍然是错误的?或者这是错误的?@ha9u63ar编译器规范中没有这方面的要求,正如Stephan引用JVM指出的那样。另请参见“”和“”…