java - 带有 static 和 final 限定符的奇怪 Java 行为

标签 java final

在我们的团队中,我们发现了一些奇怪的行为,我们同时使用了 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 值我会理解,因为静态类成员的代码是从上到下执行的。

谁能解释为什么会发生这种行为?

最佳答案

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

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

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

关于java - 带有 static 和 final 限定符的奇怪 Java 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39448160/

相关文章:

java - 类扩展了 BufferedImage,但图片不能改变。有什么办法解决这个问题吗?

java - 内联初始化的最终成员变量不知何故为空

c++ - C++ 分配器可以是最终的吗?

java - 带有 MS Access 的 JDBC 中的 "architecture mismatch between the Driver and Application"

java - 不同应用程序上的 jpa 实体

java - 如何在java中只设置变量一次

java - sleep 暂停整个线程

c++ - 检查 C++ 成员函数是否存在,可能 protected

java - 如何使用 Lombok 实例化一个包含多个对象作为字段的类?

java - 如何在camel测试中配置application.properties?