以什么顺序执行的类中的静态块和静态变量?

tr_*_*est 16 java static final

可能重复:
Java静态类初始化

为什么字符串变量在初始化块中更新而不是整数(即使先写入块)

class NewClass
{
    static 
    {
       System.out.println(NewClass.string+" "+NewClass.integer);
    }

    final static String string="static";
    final static Integer integer=1;

    public static void main(String [] args)//throws Exception
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我的输出是

static null
Run Code Online (Sandbox Code Playgroud)

PS:还注意到只有当我插入final修饰符时,字符串变量初始化才会发生在块之前.为什么会这样?为什么不是整数?我已经将它声明为最终静态

Jon*_*eet 19

从JLS的第12.4.2节开始,适当地剪断:

初始化C的过程如下:

  • 然后,初始化最终的类变量和其值为编译时常量表达式的接口字段(§8.3.2.1,§9.3.1,§13.4.9,§15.28).

  • 接下来,按文本顺序执行类的类变量初始值设定项和类的静态初始值设定项,或接口的字段初始值设定项,就好像它们是单个块一样.

因此,对于非编译时常量,它不是"所有变量"的情况,而是"所有静态初始化器",反之亦然 - 它们全部按文本顺序组合在一起.所以如果你有:

static int x = method("x");

static {
    System.out.println("init 1");
}

static int y = method("y");

static {
    System.out.println("init 2");
}

static int method(String name) {
    System.out.println(name);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后输出将是:

x
init 1
y
init 2
Run Code Online (Sandbox Code Playgroud)

即使make xyfinal也不会影响这一点,因为它们仍然不是编译时常量.

PS:还注意到只有当我插入final修饰符时,字符串变量初始化才会发生在块之前.

那时,它是一个编译时常量,并且它的任何使用基本上都是内联的.另外,如上所述,在其余初始化器之前分配变量值.

JLS的第15.28节定义了编译时常量 - 它包括所有原始值String,但包括诸如的包装类型Integer.


Kum*_*tra 7

这是一个简短而直截了当的问题解答....

static Variable :

当静态变量执行JVM 负载Class,和Class 被加载时,无论其被实例化或者它static method被调用.

static Block or static Initializer Block :

静态静态初始化块被初始化之前Class实例化之前static method被调用,即使在static variable被使用.

/////////编辑部分/////////

class NewClass {

    final static String string = "static";
    final static Integer integer = 1;

    static {
        System.out.println(NewClas.string + " " + NewClas.integer);
    }

    public static void main(String [] args) { // throws Exception
        new NewClas();
    }

}
Run Code Online (Sandbox Code Playgroud)

以上将打印 static 1.

原因在于,JVM将执行称为常数变量的预先计算的优化过程Constant folding.

此外,在您的情况下,结果static null原因Constant folding应用于原始类型而不是Wrapper对象,在您的情况下它的整数...