一尘不染

具有静态和最终限定符的奇怪Java行为

java

在我们的团队中,我们发现在使用staticfinal限定词时都有一些奇怪的行为。这是我们的测试课程:

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两次都写值,因为静态类成员的代码是从上到下执行的。

谁能解释为什么这种现象发生?


阅读 190

收藏
2020-12-03

共1个答案

一尘不染

这些是您运行程序时采取的步骤:

  1. main可以运行之前,Test必须按外观顺序通过运行静态初始化程序来初始化该类。
  2. 要初始化该me字段,请开始执行new Test()
  3. 打印的值I。由于字段类型为Integer,因此看起来像编译时常量4的值成为计算值(Integer.valueOf(4))。该字段的初始化程序尚未运行,正在打印初始值null
  4. 打印的值S。由于已使用编译时常数对其进行了初始化,因此将该值烘焙到引用站点print中abc
  5. new Test()完成,现在I执行初始化程序。

课程:如果您依赖急切初始化的静态单例,请将单例声明放置为最后一个静态字段声明,或者诉诸于在所有其他静态声明之后出现的静态初始化程序块。这将使该类看起来完全初始化为单例的构造代码。

2020-12-03