关于java:标准的Sun javac可以进行增量编译吗?

Can standard Sun javac do incremental compiling?

最近,我开始使用Eclipse的Java编译器,因为它比标准Javac快得多。有人告诉我它更快,因为它执行增量编译。但是我对此还不太确定,因为我找不到关于eclispse和sun的编译器"增量功能"的任何权威文档。 Sun的编译器总是编译每个源文件,而Eclipse的编译器只编译更改的文件以及受此更改影响的文件,这是真的吗?

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

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

用于构建我的ant。


Is it true that Sun's compiler always compiles every source file and Eclipse's compiler compile only changed files and those that are affected by such a change?

我相信您在这两个方面都是正确的。

您当然可以强制Eclipse重新编译所有内容。

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

编辑

在Ant中,可以通过两种方式完成增量编译:

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

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

    要了解为什么Ant <depend>不能做到万无一失,请阅读文档的"限制"部分。


Javac仅编译在命令行上命名或为依赖项且已过时的源文件。 Eclipse可能有一种更细粒度的方法来决定这意味着什么。


重新整理我在这里听到的内容,并为像我这样的懒惰的人改写它:

您可以使用ant中的javac任务来实现增量构建,但是您应该使用depend任务清除修改后的.java的.class文件,并且不得在javac任务中未指定include语句。 (仅在javac任务中指定src路径,并留下未指定的原因导致javac重新编译它找到的所有源。)

这是我的depends和javac任务。使用标准的Oracle Java编译器,仅编译我修改的.java文件。希望这会有所帮助!

1
2
3
4
5
6
7
8
9
10
<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>


Eclipse当然可以做到这一点。如果您已启用该选项(默认情况下),它也会在保存时间执行此操作。看起来sun也不会这样做(测试非常容易,只需创建一个小项目,其中A是使用类B的主要类,而B不使用类A。然后更改A并编译项目再次,查看b.class的时间戳是否已更改。

这是许多编译器(例如gcc)的工作方式。您可以使用ant之类的工具和make来仅编译项目已更改的部分。还要注意,这些工具并不是完美的,有时Eclipse只会失去对更改的跟踪,您需要进行完全重建。