Java 12.0.1 编译器(我这里的测试都在 MS Windows 中运行)在使用 -sourcepath 参数时有一些非常奇怪的行为,关于它决定编译的内容。解释这一点的最简单方法是提供两个示例并引用行为差异。
示例 1:
源文件“A.java”
public class A {
public static void main(String[] args) {
System.out.println("Hello World");
B.myMethod();
}
}
源文件“B.java”
public class B {
public static void myMethod() {
System.out.println("Goodbye!");
}
}
要编译示例 1,我们只需使用以下内容:
javac -sourcepath . A.java
这将编译 A.java 和 B.java 并创建 A.class 和 B.class。我们希望它也能编译 B.java,因为 A 依赖于它。现在等一下,不要修改任何一个“.java”源文件,只需重新运行上面的编译命令。你会发现它重新编译了 A.java 并创建了一个新的 A.class(带有更新的时间戳),但是 B.class 没有被重新编译。好的,这几乎是人们所期望的。现在让我们将其与下面的下一个示例进行比较。
示例 2:
源文件“example2/A.java”
package example2;
public class A {
public static void main(String[] args) {
System.out.println("Hello World");
B.myMethod();
}
}
源文件“example2/B.java”
package example2;
public class B {
public static void myMethod() {
System.out.println("Goodbye!");
}
}
源文件是一样的,除了所有的东西都被移动到一个包中。我们想编译当前位于“example2”文件夹中的两个源文件。所以我们使用下面的命令:
javac -sourcepath .. A.java
这将再次编译 A.java 和 B.java 并创建 A.class 和 B.class。这里没有问题,和以前一样。请注意,-sourcepath 现在是“..”,因为现在所有内容都在一个包中,那是“根”源文件夹。现在等一下,不要修改任何一个源文件,只需重新运行上面的编译命令即可。您会发现它重新编译了 A.java 和 B.java,并创建了一个新的 A.class 和 B.class 文件(具有更新的时间戳)。
请注意第二次运行 javac 命令时编译行为的差异。当 -sourcefile 为“.”时并且文件不在包中,第二个“javac”命令只编译命令行上指定的源文件。但是当 -sourcefile 是“..”并且类在一个包中时,第二个“javac”命令总是编译所有依赖的源文件,无论是否需要重新编译未指定的源文件。
问题是为什么?如果类文件的时间戳比源文件更新,我可以将哪些参数传递给 javac 命令行以阻止示例 2 无条件地重新编译所有相关源文件?
最佳答案
出现此问题是因为 javac 比较 .java 文件和 .class 文件之间的时间戳。它使用 -sourcepath
查找源文件,使用 -classpath
查找类文件。因此,您的问题可以通过指定类路径来解决:
javac -sourcepath .. -classpath .. A.java
关于java - 如何强制 Java 编译器只编译我指定的源文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56048512/