在我们的团队中,我们发现了一些奇怪的行为,我们同时使用了 static
和 final
限定符。这是我们的测试类:
public class Test {
public static final Test me = new Test();
public static final Integer I = 4;
public static final String S = "abc";
public Test() {
System.out.println(I);
System.out.println(S);
}
public static Test getInstance() { return me; }
public static void main(String[] args) {
Test.getInstance();
}
}
当我们运行 main
方法时,我们得到以下结果:
null
abc
如果它两次都写 null
值我会理解,因为静态类成员的代码是从上到下执行的。
谁能解释为什么会发生这种行为?
最佳答案
这些是您运行程序时所采取的步骤:
- 在
main
可以运行之前,Test
类必须通过按出现顺序运行静态初始化程序来初始化。 - 要初始化
me
字段,请开始执行new Test()
。 - 打印
I
的值。由于字段类型是Integer
,所以看起来像编译时常量4
的东西变成了计算值 (Integer.valueOf(4)
)。该字段的初始化器尚未运行,打印初始值null
。 - 打印
S
的值。由于它是使用编译时常量初始化的,因此该值被烘焙到引用站点中,打印abc
。 new Test()
完成,现在执行I
的初始化程序。
教训:如果您依赖于急切初始化的静态单例,请将单例声明作为最后一个静态字段声明,或者求助于在所有其他静态声明之后出现的静态初始化程序 block 。这将使类看起来完全初始化为单例的构造代码。
关于java - 带有 static 和 final 限定符的奇怪 Java 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39448160/