javac 和 Eclipse 编译器有啥区别?
Posted
技术标签:
【中文标题】javac 和 Eclipse 编译器有啥区别?【英文标题】:What is the difference between javac and the Eclipse compiler?javac 和 Eclipse 编译器有什么区别? 【发布时间】:2011-03-04 22:47:23 【问题描述】:Eclipse 的 Java 编译器只是封装了 javac
程序所封装的同一个内核,还是完全是一个单独的编译器?如果是后者,他们为什么要重新发明***?
【问题讨论】:
【参考方案1】:Eclipse 已经实现了自己的编译器,称为Eclipse Compiler for Java (ECJ)。
它与 javac 不同,javac 是 Sun JDK 附带的编译器。一个显着的区别是 Eclipse 编译器允许您运行实际上没有正确编译的代码。如果出现错误的代码块从未运行,您的程序将运行良好。否则,它将抛出一个异常,表明您尝试运行无法编译的代码。
另一个区别是 Eclipse 编译器允许在 Eclipse IDE 中进行增量构建,也就是说,一旦您完成输入,所有代码就会被编译。
Eclipse 自带编译器这一事实也很明显,因为您可以在 Eclipse 中编写、编译和运行 Java 代码,甚至无需安装 Java SDK。
ECJ 优于 javac 的几个例子是:
Apache Tomcat 使用 ECJ 编译 JSP, IntelliJ IDEA 支持 ECJ,从 GNU Compiler for Java (GCJ) 4.3 开始, GCJ 与 ECJ 集成, Liferay 使用 ECJ 构建。【讨论】:
@Bart,Eclipse 编译器可以很好地用于企业版本构建。 @jinguy 我不同意您应该使用 Eclipse 编译器进行发布。正如你在答案中所说,它可以编译有错误的代码,你不想要像 public void foo() throw new Error("Unresolved compiler problem: \n\tFOOBAR cannot be resolved\n"); 这样的东西。 出现在我的生产代码中。 @Matthew Farwell 他没有说你应该,但你可以。如果您创建的构建中有错误,那么首先您的构建过程就有问题。 请注意,在您的应用程序中嵌入 ECJ 允许您的程序在 JRE 下运行,而不需要 JDK。 @MatthewFarwell 在此处关闭循环:对于发布版本,建议您简单地不指定编译器参数-proceedOnError
,它根本不会从有错误的来源。【参考方案2】:
每个人都已经解释过它们是不同的。以下是我注意到的两个编译器之间的一些行为差异。它们都归结为(至少)其中一种实现中的错误。
编译时优化相关
Eclipse bug? Switching on a null with only default case泛型类型推断相关
Generics compiles and runs in Eclipse, but doesn’t compile in javac Compilers behave differently with a null parameter of a generic method【讨论】:
事实上,经过一个漫长的夜晚,我知道了这种差异:Eclipse 报告了一个错误,关于我认为合法的事情(我不记得是什么),在我绝望中(我几乎无法保持清醒)我只是将代码提供给 javac,然后它运行顺利!我在 Google 中发现我必须升级 JDT 才能修复该问题。 我发现编译器在处理复杂情况下的泛型之间存在许多差异。如果您想将它们添加到您的答案中,我在这里提出了两个问题:***.com/questions/13501836/…***.com/questions/13980552/… 根据 JLS,匿名类永远不是静态的,但它们可以在静态范围内声明。当使用反射来询问这样的类是否是静态的时,ECJ 生成的代码在 javac 的says yes 中说不。相关帖子here. 所发出的字节码中的任何语义差异都是任一实现中的错误。在我看来,这不是很有趣。只需列出 javac 和 ecj 中的开放错误,我就可以轻松生成一长串此类“差异”。 仅供参考,Netbeans 没有任何此类“差异”,因为它使用 javac 的内部 API 来完成 EJC 所做的一切。【参考方案3】:Eclipse 的内置编译器基于 IBM 的 Jikes java compiler。 (请注意,Eclipse 也是在 IBM 开始的)。在JDK中完全独立于Sun的Java编译器;它不是 Sun 的 javac
的封装。
Jikes 已经存在很长时间了,它曾经比标准的 JDK Java 编译器快很多(但我不知道这是否仍然正确)。至于 IBM 为什么要编写自己的 Java 编译器:可能是因为许可原因(他们也有自己的 Java 实现)。
【讨论】:
他们并没有真的编写自己的 Java 编译器。 Eclipse 在 Java 出现之前就可以追溯到 Visual Age for Smalltalk。由于这两种语言实际上有些相似,因此它们只是调整了现有技术。 Sun 的编译器也完全不适合在 IDE 中使用,尤其是在像最初的 Visual Age for Java 这样的增量 Smalltalk 风格的 IDE 中,因为它总是想要编译整个文件。 IBM 的编译器只能增量编译已更改的片段。它甚至可以编译甚至不是合法Java的sn-ps,在 Eclipse 剪贴簿,您可以在其中简单地编写代码的 sn-ps、突出显示并运行它们,而无需将它们放入类、主方法甚至方法中 . @JörgWMittag 实际上,javac 的内部 API(由 Netbeans 使用)可用于实现所有相同的目标。 @AleksandrDubinsky:这在 1997 年 Visual Age for Java 发布时的实际效果如何?【参考方案4】:它完全是一个单独的编译器。这是必需的,因为 javac 不允许编译来自 the eclipse site 的轻微损坏的代码
增量 Java 编译器。作为 Eclipse 构建器实现,它基于从 VisualAge for Java 编译器演变而来的技术。特别是,它允许运行和调试仍然包含未解决错误的代码。
【讨论】:
为什么要编译“轻微”损坏的代码? @SteveCohen:因为您希望编译器在您编写代码时提供语法高亮、语义高亮、重构支持、类型检查、代码完成、提示以及编译器所做的所有其他事情,当您编写代码时,根据定义,它或多或少是不完整的(否则,您为什么还要编写它?)一个仅在项目结束时工作的 IDE,当一切都已经实现时,将是相当没用。以上是关于javac 和 Eclipse 编译器有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
在做java开发时,build和compile有啥联系和区别?谢谢。