导入的 java 类中的公共静态最终变量

2022-09-02 20:34:37

我碰巧在工作场所遇到Java代码。下面是场景:有 2 个类 - 和 .ClassAClassB

ClassA除了其中的 4 个公共静态最终字符串值外,什么都没有。它的目的是使用这些值,比如(不要问我为什么,这不是我的代码)。ClassA.variable

ClassB进口。我编辑了字符串值并进行了编译。当我跑步时,我可以看到它使用的是旧值 - 而不是新值。我不得不重新编译以使其使用来自的新值!(我不得不重新编译其他导入的类!ClassAClassAClassBClassBClassAClassA

这仅仅是因为JDK 1.6还是我应该早点知道重新编译!启发我。:)ClassB


答案 1

如果类中的变量值恰好是编译时常量,则编译器可能已使用它们内联到类中,而不是生成运行时引用。我想,这就是你所描述的案件中发生的事情。finalClassAClassA

例:

public class Flags {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

public class Consumer {
    public static void main(String[] args) {
         System.out.println(Flags.FOO);
    }
}

在此示例中,编译器可能会将 的值合并到 生成的代码中,而不是生成等效的运行时引用。如果以后的值发生更改,则必须重新编译才能使其使用新值。FOOConsumerFOOConsumer

这是一种优化,在编译程序的效率和速度方面具有一些优势。例如,内联该值可能会在使用它的表达式中实现进一步的优化,例如:

int x = Flags.FOO * 10;

在此示例中,内联值(此处:1)使编译器能够注意到乘法没有区别,可以完全省略。


答案 2

这是一个二进制兼容性问题。对常量字段的引用在编译时解析。你看到的行为是正确的;如果更改类 A 中的值,则必须重新编译客户端(B 类)。为避免此类问题,请考虑使用 Java 5.0 版中引入的枚举类型添加常量。


推荐