public class ChangeALot { public static final boolean debug=false; public static boolean log=false; }
public class EternallyConstant { public static void main(String [] args) { System.out.println("EternallyConstant beginning execution"); if (ChangeALot.debug) System.out.println("Debug mode is on"); if (ChangeALot.log) System.out.println("Logging mode is on"); } }
惊奇吧!在log成员上有一个'ifeq'检查,而代码根本没有检查debug成员。因为debug成员被标记为final类型,编译器知道debug成员在运行时永远不会改变,因此它通过移除'if'声明进行优化。这确实是一个非常有用的优化,因为它允许你在程序中嵌入调试代码而在将它设置为false时不用付出运行时的代价。不幸的是这个优化能够导致主要的编译时混乱。如果你改变一个final成员,你必须记住重新编译任何可能引用该成员的类。这是因为这个'reference'可能已经经过优化了。Java开发环境不能总是发现这个微妙的相关性,一些能导致非常奇怪的错误。因此,古老的C++格言对于java环境仍然有效:"When in doubt, rebuild all."(有疑问,重新编译所有的代码)。