Java静态final字段初始化顺序

标签 java constructor static final static-members

我试图理解当使用对同一封闭类对象的引用来初始化静态字段时初始化顺序的行为。

public class Test {

        static final Test t=new Test();
        static int a=5;

        Test(){
            System.out.println("a="+a);
        }

        public static void main(String[] args) {
            new Test();
        }

    }

上面这段代码的输出是:

a=0
a=5

如果我将变量 a 修改为普通 static 以外的任何其他内容:

static final a=5;
a=5;
final a=5;

输出是:

a=5
a=5

为什么会这样?

请注意,即使 t 和 a 都声明为 static final,在这种情况下,输出也是 a=5 & a=5 ta

的声明之前

最佳答案

静态最终成员在其他静态成员之前初始化。

非final静态成员按出现顺序初始化

因此,在您的第一种情况下:

    static Test t=new Test();
    static int a=5;

a初始化之前先调用构造函数,所以显示a=0

在第二种情况下,static final at之前被初始化,所以a=5在第一个实例时显示>测试 已创建。当 a 不是静态时,它会在构造函数执行之前进行初始化,因此再次显示 a=5

关于您问题中的修改。

查看 12.4.2 of the JLS 部分:

  1. Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

...

  1. Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

您看到最终类变量(即 static final)只有在它们的值是编译时 constant expressions 时才会在其余静态变量之前初始化。 . 5 是常量表达式。 new Test() 不是。因此 at 之前初始化,即使两者都是静态最终的。

关于Java静态final字段初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27859435/

相关文章:

c++ - 检查静态库/可执行文件的依赖关系

javascript - TypeScript 嵌套静态属性

function - 将构造函数视为 Scala 中的函数 - 如何将构造函数放入映射中?

c# - 通过转换 (ChildClass)parentObject 调用子构造函数;跟踪修订

java - Eclipse 插件,编辑器中的弹出菜单发生在哪里?

java - 如何确定 Java 进程的 CPU 利用率为 100%

c++ - 定义或声明中的成员初始值设定项列表?

C++ 指向函数的静态指针

java - RestFB:当页面的 URI 具有页面名称时无法获取页面帖子

java - 无法使用外部 jar 文件在远程命令行中运行 java