Java 蚂蚁不';t重新编译常数
我有一个Java项目,它涉及类Java 蚂蚁不';t重新编译常数,java,ant,Java,Ant,我有一个Java项目,它涉及类GUIConstants——用于布局GUI的各种公共静态final参数,因为不同的组件有时必须具有相同的大小或颜色或其他 我目前正在做一个视觉上的重新设计,包括改变一些常数。然而,ant使这一点变得困难。我将更改一个参数并重新编译,但仍然使用旧值。如果我对使用它的某个文件添加一些琐碎的修改并重新编译,将使用正确的值。但是,跟踪所有文件并修改它们很烦人而且容易出错。当然有办法强迫ant重新编译未更改的文件……我只是在手册页中找不到它 旁注:我的假设是,当编译一个使用f
GUIConstants
——用于布局GUI的各种公共静态final
参数,因为不同的组件有时必须具有相同的大小或颜色或其他
我目前正在做一个视觉上的重新设计,包括改变一些常数。然而,ant
使这一点变得困难。我将更改一个参数并重新编译,但仍然使用旧值。如果我对使用它的某个文件添加一些琐碎的修改并重新编译,将使用正确的值。但是,跟踪所有文件并修改它们很烦人而且容易出错。当然有办法强迫ant重新编译未更改的文件……我只是在手册页中找不到它
旁注:我的假设是,当编译一个使用final
变量的类时,Java使用的是值本身,而不是变量指向的任何对象的引用(类似于在C中使用#DEFINE
for constants的方式)。因此,即使变量指向其他对象,原始值也会烘焙到.class
文件中。这是真的吗?(这不影响我的问题,我只是好奇。)
提前感谢。您想使用一个
清除
任务来删除dist目录中的所有文件。或者无论你在哪里放置二进制文件。你的理论是错误的。Java将finish嵌入到周围类文件的常量池中,就像它嵌入任何非finish一样。没有特殊的“最终”优化,只有一个标志指示只能在构建期间设置
构建链中出现某种错误的可能性要大得多,比如从旧源“更新”的类或类集,或者从尚未更新的类“构建”的jar文件,或者从以前的构建中引用jar文件的程序,等等。验证这一点的一种快速方法是删除所有编译项。这通常是通过ant build.xml文件中的“clean”目标完成的;然而,这个目标也可能是手工编写的,所以不要假设它总是正确的(特别是如果您添加了额外的中间构建步骤,如类增强等)。您的假设几乎是正确的。它不是简单的
final
变量,而是所谓的“”:
我们将一个原语类型或字符串类型的变量称为常量变量,它是final,并用编译时常量表达式()初始化。变量是否为常量变量可能涉及类初始化()、二进制兼容性(、)和确定赋值()
然后在关于:
对常量变量(§4.12.4)字段的引用在编译时解析为表示的常量值。二进制文件中的代码中不应出现对此类常量字段的引用(包含常量字段的类或接口除外,该类或接口将有代码对其进行初始化)
(我的重点是):
如果字段是常量变量(§4.12.4),则删除关键字final或更改其值不会导致与先前存在的二进制文件不运行,从而破坏与它们的兼容性,但是除非重新编译,否则它们将看不到字段使用的任何新值
在以前的工作中,我们利用它来拥有一种条件编译系统,这样我们就可以生成包含所有调试语句的生产二进制文件
当您将其与确定要重新编译的类的方式相结合时,您将获得所看到的行为:
只编译没有相应的.class文件或类文件比.Java文件旧的Java文件
注意:ApacheAnt仅使用源文件和类文件的名称来查找需要重建的类。它不会扫描源文件,因此不了解嵌套类、与源文件命名不同的类等。请参阅基于存在/修改时间之外的依赖项检查任务
解决这一问题的最简单方法是每次都进行干净的完整编译,使用类似于antcleancipile
(假设您有一个clean
目标删除所有类文件)。但这可能太慢了
我还打算建议您查看该任务,正如javac
任务文档中所建议的那样,但是查看该任务的文档(我自己并没有实际使用过)似乎没有什么帮助(请参阅标题为“限制”的部分):
这些限制最明显的例子是,当其他类导出的常量基元数据类型发生更改时,任务无法判断要重新编译哪些类
如果您发现每次执行干净编译都太慢,一个可能的解决方法是使GUIConstants
类中的值不是常量,至少在进行更改时是这样。您可以通过注释掉所有final
关键字使值成为非final,然后其他类应该会看到您的更改。当您对新值感到满意时,将最终的放回并重新编译(并测试所有内容是否仍然正常工作)。两个“理论”似乎都不正确,删除静态无效,从clean重新编译始终有效,我的构建“系统”它几乎只依赖于子目录中的源代码,而不依赖于其他外部jar,所以没有“过时”类
在我的例子中,我必须对我的源代码的一个区域进行完整的重建-我直接从源代码中包含一个库,它不需要重新编译,但被单独的“deepclean”规则包含,但与此问题无关…DJClayworth在这方面的回答建议使用
public static final int INT_VALUE = Integer.valueOf(100).intValue();