1

我正在研究 Java 中的静态初始化程序。我通过以下源代码获得:

    public class A {
       private static int count = 5;
       final static int STEP = 10;
       boolean alive;
       static {
         count = 1;
       }
       public static void main(String[] args) {
          A a = new A();
          System.out.println(A.count);
       }
    }

我的问题是为什么编译器没有抱怨在静态初始化块中重新分配了变量的值count。我知道 Java 允许前向引用,只要遵循声明前读取规则(即在声明之前不应读取任何标识符),这适用于所有初始化程序,如果没有,则引用(或标识符)必须位于左侧 -手边的任务。我还知道,如果在一个类中编写多个静态初始化表达式和静态字段初始化块,那么它们的执行顺序是连续的。 1count = 1

根据我的执行流程应该是:加载类,然后按顺序执行所有静态初始化程序(表达式和块),因此count将初始化为值5,然后执行默认构造函数调用 super () 并将实例变量初始化alive为默认值。但是为什么它没有抛出静态变量count已重新初始化的错误(因为它不是前向引用的情况),而是给出了输出1。这是否意味着我们可以通过静态初始化块重新初始化静态变量?

4

2 回答 2

2

由于您的类变量在使用前出现,没关系。

这是language specification#Static Initializers相同的

类中声明的静态初始化程序在类初始化时执行(第 12.4.2 节)。与类变量的任何字段初始化器(第 8.3.2 节)一起,静态初始化器可用于初始化类的类变量。

有时限制使用在使用后以文本形式出现声明的类变量,即使这些类变量在范围内。有关管理对类变量的前向引用的精确规则,请参见第 8.3.3 节。

于 2017-07-04T11:13:20.987 回答
1

只要您在初始化的类中操作静态变量,编译器就不会出错。如果您已将其声明为最终行为,则您提到的行为将会发生。请记住,静态意味着该变量在对象的所有实例之间共享,因此它只会被初始化并分配一次内存。

于 2017-07-04T11:24:19.700 回答