【问题标题】:Do Linux and Windows java compilers produce the same or different class files?Linux 和 Windows java 编译器生成相同还是不同的类文件?
【发布时间】:2013-10-01 16:09:19
【问题描述】:

我们在 Linux 和 Windows 上使用相同的 1.6.0_25 版本进行 Java 编译。

由于某种原因,生成的类文件不同。对吗?

【问题讨论】:

  • 由于多种原因,文件在字节级别上可能有所不同。然而就 JVM 而言它们是相同的,即你可以运行任何类文件,无论你在哪里编译它,只要编译的 JDK 是兼容的版本。
  • 类文件格式、字节码和语言的语义都被正式指定。虽然您可能会看到一些差异,但如果它们产生不同的行为,那就是编译器错误。
  • 这就是问题 - 关于字节比较。这与在不同平台上运行无关。
  • 字节比较并不能真正告诉你任何事情。例如,将类中的方法写入类文件的顺序无关紧要。因此,如果您有一个类Foo() 和方法bar()baz(),一个编译器运行将首先按该顺序写出这些方法的字节码,另一个编译器将以相反的顺序执行它。例如,如果编译器将有关这些方法的信息存储在哈希映射中,则可能会发生这种情况。 (hashCode() 不保证在程序调用之间为相同的值返回相同的结果,实际上如果不这样做会更好。)
  • 我们的目标是确定生产war文件和最新版本的对应关系,所以我们使用Beyond Compare的字节比较

标签: java linux windows compilation


【解决方案1】:

java 编译器不是确定性的,如果在同一平台上多次编译或在不同平台上编译,可能不会生成相同的 .class。我试图弄清楚 java 编译器的内部结构,看看为什么它不是确定性的。

在了解javac 中的交叉编译选项时,进一步搜索它可以提供更多见解:

交叉编译选项

默认情况下,类是针对引导程序和扩展程序编译的 javac 附带的平台的类。但是javac也 支持交叉编译,其中类是针对一个 不同 Java 平台的引导和扩展类 执行。使用 -bootclasspath 和 -extdirs 很重要 交叉编译时;请参阅下面的交叉编译示例。

【讨论】:

  • 这和我们的案例有什么关系:相同的源文件编译在不同的平台上?编译是否产生相同的类文件?
  • @anarinsky 忘记该选项,但检查粗体部分“默认情况下,类是根据 javac 附带的平台的引导和扩展类编译的。”
  • @JunedAhsan 我不确定这会导致字节码级别的差异。引导类仅通过名称从您的 .class 文件中引用。
  • ... 但是 Java 编译器是用 Java 本身编写的(至少旧版本是这样),因此在两个操作系统上使用相同的编译器。
【解决方案2】:

Java 字节码与平台无关。

【讨论】:

  • 是的,但有些部分可能会有所不同,但仍然是等效文件。
  • 谢谢,大小一样还是不一样?
  • 您使用的是 OpenJDK 还是 Oracle 的?使用相同的选项、标志和编译器版本,生成的文件将具有相同的大小。 stackoverflow.com/questions/5786586/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 2014-04-01
  • 2013-01-02
  • 1970-01-01
相关资源
最近更新 更多