为什么Java依赖于常量会导致重新编译?

Nei*_*own 9 java ant

我有几个简单的类:

// src/Consts.java
public class Consts
{
    public static final int A = 100;
    public static final int B = 101;
}
Run Code Online (Sandbox Code Playgroud)

和:

// src/Print.java
public class Print
{
    public static void main(String[] args)
    {
        System.out.println("A: " + Consts.A + " B: " + Consts.B);
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个简单的ant构建文件:

<project name="Test" default="compile" basedir=".">
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>

  <target name="compile">
    <mkdir dir="${build}"/>
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}" debug="on" />
  </target>

  <target name="clean">
    <delete dir="${build}"/>
  </target>
</project>
Run Code Online (Sandbox Code Playgroud)

我跑ant,然后跑java -cp build Print,我得到我期望的输出,A: 100, B: 101.精细.然后我编辑Consts.java来设置A = 200和B = 201并重新运行ant.它说"编译1个源文件",即Consts.java(通过查看类文件的时间戳确认).然后我重新运行java -cp build Print并打印出来A: 100, B: 101.至少可以说这是出乎意料的.

谷歌搜索表明,Consts中的值在编译时被替换为Print源.哪个问题,但我的问题是:为什么ant + javac在Consts改变时没有重新编译打印? 两者之间存在明确的编译时依赖关系.

(我刚刚有点所以很难通过这个问题,在我看来,这肯定是在的工具之一的错误.还是我失去了一些东西?)

Nei*_*own 4

在看到安迪·特纳的链接后,我进一步观察了一下,我认为 ant 比我想象的要愚蠢得多。来自javac 任务

注意:Apache Ant 仅使用源文件和类文件的名称来查找需要重建的类。它不会扫描源文件,因此不会了解嵌套类、与源文件命名不同的类等等。请参阅基于存在/修改时间以外的依赖性检查的任务。

提到的依赖任务甚至明确说明了这一点:

这些限制最明显的例子是,当其他类导出的常量原始数据类型发生更改时,任务无法确定要重新编译哪些类。例如,定义的更改类似于

公共最终类常量{公共最终静态布尔DEBUG = false; }

不会被其他班级接走。

这似乎准确地描述了我的情况。我认为这一切给我的教训是:(a)不要使用 ant,(b)如果使用,请务必在构建之前进行清理。