类没有自动编译

时间:2013-11-19 23:11:18

标签: java windows command-line javac

Javac成功地重新编译了我的所有类,除了一个我叫做“Box.java”的类。如果特别要求,Javac会编译它:javac Box.java,但不能作为整个项目重新编译的一部分。

  1. 我是否正确地认为这是因为事实证明,有一个名为“Box”的类(Swing的一部分我相信,我一般在其他地方使用Swing)?通过重命名我的类(以及相关的方法等)“DecisionBox.java”,问题似乎消失了。

  2. 如果这是对的,那么将来避免的最佳方法是什么。我可以很容易地找到一个Java保留字列表,但保留类....?只搜索JavaDocs?或者IDE会发现此错误吗?

  3. 我只是问,因为没有错误消息需要很长时间才能找到一个类没有被重新编译...

1 个答案:

答案 0 :(得分:2)

这取决于你如何编译整个项目,以及你的其他源文件如何使用Box。

Java编译器将自动编译依赖项。您有一个名为Box的类与javax.swing.Box同名,这不是问题,因为包名称用于区分。

但是,例如,您编译的其他类都不是指您的 Box。例如,如果您在任何地方import javax.swing.*,然后只使用Box,则该类很可能正在使用javax.swing.Box。如果编译器始终可以将Box解析为javax.swing.Box,则没有理由编译Box,因为就其而言,您永远不会使用它。

如果您使用源文件的默认包(即没有包),这可能会引发更多混淆。您希望保持井井有条,并尽可能明确地了解包。使用默认包意味着您无法明确限定自己类的名称。

确保您确保从包中导入特定类而不是javax.swing.*,并且如果您需要在同一源文件中同时使用Boxjavax.swing.Box,请明确指定包名称。

换句话说,听起来好像编译器在某些时候没有看到你的 Box是你的类正在使用的那个 - 以及显式导入和完全使用合格的包名可以消除这种混淆。

您可以尝试的一个实验是删除所有已编译的.class文件,然后重新编译您的项目。如果永远不会编译Box.java,那么即使您认为自己可以使用它,也可能不会使用它。

基本上,如果有的话,这是不使用通配符包导入的好例子。通过始终显式导入您正在使用的类,您可以显着降低编译器对您的意图做出错误假设的机会。这(以及在较小程度上,不使用默认包)是避免将来出现这种情况的最佳方法。

根据评论中的新信息进行更新:OP有一个关系图,如:

 FirstClass
     Topic
         Boat
         DecisionBox

Boat / DecisionBox在修改后不会重新编译的原因是Topic没有改变。因此,当您重新编译FirstClass时,它会检查TopicTopic不需要重新编译,因此不会检查Topic的依赖项。如果FirstClass直接引用Boat(即使例如Topic.getBoat()),则会重新编译Boat。这是javac非常基本的依赖性行走的缺点。在重新编译之前删除所有.class,或者你可以使用其他一些构建系统,比如ant(你可以指定依赖项)或IDE的内部系统(例如,大多数IDE会为你神奇地处理这个问题,尽管学习当然很好命令行界面,实际上很少在没有补充构建系统的情况下使用它。)

<小时/> 顺便说一句,另一种可能性,虽然这种可能性要小得多,但是Box.java或编译Box.class上的一些不正确的时间戳会导致编译器认为它没有改变,因此不需要重新编译。如果.java文件上的时间戳比.class文件新,或者.class不存在,则只会重新编译该文件。