2010-04-07 52 views
19

最近我开始使用Eclipse的java编译器,因为它比标准的javac快得多。我被告知它更快,因为它执行增量编译。但是我仍然有点不确定,因为我找不到关于这两者的权威性文档 - eclispse和sun's - 编译器“增量特性”。 Sun的编译器是否总是编译每个源文件并且Eclipse的编译器仅编译已更改的文件以及受此类更改影响的文件?标准的Sun javac可以进行增量编译吗?

编辑:我不使用Eclipse的自动构建功能,而是我设置

-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter 

我的蚂蚁构建。

+1

Oracle已经努力用'sjavac'工具来解决这个问题。相关问题:http://stackoverflow.com/questions/26424759/what-is-sjavac-who-is-it-for-and-how-do-i-use-it – aioobe 2014-10-29 14:43:19

回答

14

这是真的,Sun的编译器总是编译所有的源文件和Eclipse的编译器编译只改文件和那些受影响的文件通过这样的改变?

我相信你在两方面都是正确的。

你当然可以强制Eclipse重新编译一切。

但等式的另一部分是Java构建工具(如Ant和Maven)只能编译已更改的类以及它们的依赖类树。

编辑

在蚂蚁,渐进式编译可以通过两种方式来完成:

  • 默认情况下,<javac> task.java相应.class文件的时间戳和进行比较,只告诉Java编译器重新编译比相应的目标(.class)文件更新或者根本没有目标文件的源文件(.java)。

  • <depend> task还考虑了类之间的依赖关系,它通过读取和分析嵌入在.class文件中的依赖性信息来确定。确定哪些.class文件已过期后,<depend>任务将删除它们,以便以下<javac>任务将重新编译它们。但是,这并非完全可以证明的。例如,对源代码进行大量更改可能会导致<depend>任务可能正在分析陈旧的依赖关系。还有某些种类的依赖关系(例如静态常量)在.class文件格式中并不明显。

    要理解为什么Ant <depend>不是防呆的,请阅读documentation的“限制”部分。

+0

你能解释一下如何用Ant部分编译工作? Ant如何强制Sun的编译器仅编译已更改的文件并忽略源代码树中的其他文件? – 2010-04-07 11:12:16

+0

我想你回答了我原来的问题,但是当你提供更多信息时,我越来越困惑。如果我理解正确,在我看来,javac任务没有以前的清理是非常危险的操作,因为如果他们的时间戳没有改变,它不编译相关的类。 (有趣的是,我只是意识到我昨天有过这个问题,看起来对我来说完全是个谜。) – 2010-04-07 12:22:35

+0

为什么你需要编译一个依赖类,如果它没有改变? – 2010-12-04 01:13:57

2

Eclipse肯定会这样做。如果你打开了这个选项(它是默认的),它也可以在保存时进行。它看起来像太阳也不会这样做(这很容易测试,只是做一个小项目,其中A是使用类B的主类,但B不使用类A.然后更改A并编译项目再看看b.class的时间戳是否发生了变化

这是许多编译器工作的方式(例如gcc),你可以使用像ant和make这样的工具来编译只改变项目的部分。这些工具是不完美的,有时偏食刚失去的变化轨迹,你需要做一个全面的重建。

3

Javac只编译在命令行中命名的或者是依赖关系且已过期的源文件。 Eclipse可能会用更细致的方式来决定这意味着什么。

+0

你能链接一些支持这个答案的文档吗?我认为1)依赖不是由纯javac编译的,2)Eclipse有它自己的,完全不同的编译器,而不仅仅是更细致的决定方式。我无法证明这一点,但这就是为什么我问:)... – 2010-12-08 20:37:36

+0

http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#searching。当然你可以证明这一点:只要设定我描述的条件,你就会看到自己。 – EJP 2010-12-09 07:00:00

+0

这是正确的:javac编译你告诉它编译的文件,而不是“每个源文件”。它不会自行决定哪些文件需要编译,因此在OP所询问的意义上它不是递增的。进一步的(正如EJP所说),当javac正在编译class A并且发现A依赖的其他.java文件时,它(取决于许多因素)也编译它们。这与查找可能受到A.java更改影响的文件不同,我认为这就是人们感到困惑的地方。 – gatkin 2012-03-26 23:43:00

2

重申发布我在这里听到造句它懒惰的人喜欢我:

可以实现增量构建与蚂蚁javac任务,但你应该使用取决于任务,以清除.class文件的你的修改过的.java和你不能在javac任务中没有指定includes语句。 (在javac任务中只指定src路径并保留包含未指定的原因导致javac重新编译它找到的所有源。)

这里是我的依赖和javac任务。使用标准的Oracle java编译器,我只修改了.java文件。希望这可以帮助!

<depend srcdir="JavaSource" destdir="${target.classes}" cache="${dependencies.dir}" closure="yes"> 
    <classpath refid="compiler.classpath" /> 
    <include name="**/*.java"/> 
</depend> 

<javac destdir="${target.classes}" debug="true" debuglevel="${debug.features}" optimize="${optimize.flag}" fork="yes" deprecation="no" source="1.6" target="1.6" encoding="UTF-8" includeantruntime="no"> 
    <classpath refid="compiler.classpath"/> 
    <src path="JavaSource"/> 
    <include name="**/*.java" /> <!-- This enables the incremental build --> 
</javac> 
相关问题