为什么javac重新编译我的.java,虽然.class已经更新?

问题描述:

有人告诉我,javac是足够聪明,它不重新编译.java,在条件,这.java有之前的.class时间戳。我只是发现它在我的机器中不能这样工作,我当然在某处错了吗?为什么javac重新编译我的.java,虽然.class已经更新?

P.java位于.../eg/access下,以声明为包访问

eg 
|- access 
     |- P.class 
     |- P.java 

然后当我运行javac P.java的,每次它重新编译P.java,是正常还是我错了?

+1

我不会直接使用'javac'。相反,我会使用像maven,ant或IDE这样的构建工具,这些工具在整个过程中都非常聪明。 –

+0

只需注意:如果你有'package'类的'P'作为第一个声明,那么你应该从'eg'目录编译为'javac access/P.java'。 –

这是正常的,它是每次重新编译。 javac不会执行增量编译。

+0

但是,“javac编译器在源文件和类文件的类路径中查找,重新编译源代码(并重新生成类文件),如果它是较新的。”来自http://www.cis.upenn.edu /〜bcpierce/courses/629/jdkdocs/tooldocs/win32/javac.html – zell

+1

@zell不知道这个文档有多大,但它看起来很老。它可能已经被我在我的答案中提到的命令行选项所取代,就我所知,该子句不在新的等效文档中。 – berry120

+1

@zell,查看页面上的标题:星期三,10九月1997 20:40:24 GMT是页面被修改的最后一次。就我个人而言,我相信Sun/Oracle文档。 –

我想你可能会混淆javac的命令行可执行文件,javac task in Apache Antjavac总是重新编译源文件,无论是比二进制文件更旧还是更新。 Ant很聪明,能够确定文件何时需要重新编译,但是当然,您必须使用Ant构建系统才能使用此功能。

javac的默认重新编译一切每次。你观察到的行为是正确的,并通过设计。

看起来你可以指定这个行为虽然一个选项:

-Xprefer:{更新,源}

指定读取的文件当两个源文件和类文件被发现的类型。 (请参阅搜索类型)。如果使用-Xprefer:使用较新的,它将读取某个类型的源或类文件的较新者(默认值)。如果使用-Xprefer:source选项,它将读取源文件。使用-Xprefer:来源如果您想确保任何注释处理器都可以访问使用SOURCE保留策略声明的注释。

摘自:http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html

你也可能会想Eclipse的编译器,我敢肯定不会做增量编译 - 或在蚂蚁javac任务是足够聪明,想出这样的情况。

+1

实际上,-Xprefer修改类*的搜索首选项*未在命令行中指定*。因此,如果我执行javac Foo.java并引用Bar类,并且java编译器同时找到Bar.java *和* Bar.class,则此选项指定将使用哪一个编译Foo。它不会影响Foo.java是否重新编译。请参阅http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#searching –