Java 使用ant重新编译会导致代码在运行时崩溃吗?
我有一个简单的java项目,我正在使用ant构建它。它有以下两类: A.java:Java 使用ant重新编译会导致代码在运行时崩溃吗?,java,ant,compilation,Java,Ant,Compilation,我有一个简单的java项目,我正在使用ant构建它。它有以下两类: A.java: public class A { public static void main(String[] args) { Integer i = 0; B.f(i); } } B.java: public class B { public static void f(int i) { System.out.println("hello");
public class A {
public static void main(String[] args) {
Integer i = 0;
B.f(i);
}
}
B.java:
public class B {
public static void f(int i) {
System.out.println("hello");
}
}
哪种方法很好:
$ ant compile
[...]
$ java -cp bin A
hello
现在,如果我将B.f
中的int
参数更改为对象
:
public class B {
public static void f(Object i) {
System.out.println("hello");
}
}
…代码重新编译得很好
$ ant compile
[...]
$ java -cp bin A
Exception in thread "main" java.lang.NoSuchMethodError: B.f(I)V
at A.main(Unknown Source)
。。。但它在运行时崩溃。为什么?
编译前的文件夹结构:
bin
build.xml
src
├── A.java
└── B.java
build.xml:
<project>
<target name="compile">
<javac srcdir="src" destdir="bin"/>
</target>
</project>
Ant将只编译自上次编译以来未更改的文件(除非清除)。也就是说,只有一个文件发生了更改,而另一个文件正在打电话,希望使用旧版本。如果在运行ant构建之前删除所有类文件,我敢打赌它一定会工作 在ant任务的apache文档中指出: 将递归扫描源目录和目标目录以查找 要编译的Java源文件。只有没有 对应的.class文件或类文件比 .java文件将被编译 这些方法可能在源代码级别兼容,但当编译成字节码时,它们具有其他类正在寻找的特定签名。您更改了已编译签名,因此它找不到正在查找的方法 ------------编辑------------------ 可以将简单的清理任务添加到构建中:
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
您可以添加一个完整的重建:
<target name="fullReBuild" depends="clean compile">
</target>
然后根据需要从命令行发出
ant fullReBuild
。默认情况下,除非文件日期更改,否则ant不会重新编译任何内容。解决方法是使用任务。这使得ant在依赖项发生变化时重新编译依赖项。这听起来相当可疑。这意味着ant的重新编译策略几乎是无用的,每次编译时,您也可以删除所有的类。然而,A
不应该仍然使用新的B
,因为参数是兼容的吗?@Dog,我可能错了,但是你是否尝试删除类文件并运行ant构建?从你评论中的链接来看,似乎必须使用
任务才能使重新编译正常工作。@Dog,这取决于你所说的正常工作。Ant不会重新编译未更改的内容,以便在大型项目上快速构建。大多数人为“clean”创建另一个目标,并在需要完全重建时在ant
之前使用ant clean
。请参阅上面的我的编辑。您知道
?它似乎解决了已更改类的依赖项的传递闭包问题,然后重新编译它们,因此就我所见,应该可以很好地工作。它解决了我的问题。如果我创建了一个clean
目标(我已经有了),我如何知道何时使用clean
而不是重新编译?这个问题刚刚发生在我身上,我花了两个小时才找到,因为事情在随机的时间之后就崩溃了。当我进行此更改时,我怎么知道我应该使用clean
?