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



可能重复:
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
{
}
}

我的输出是

static null

第页。S: 还注意到,只有当我插入最后一个修饰符时,字符串变量初始化才会发生在块之前。为什么?为什么不为整数呢?我已经宣布它是最终静态太

从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;
}

那么输出将是:

x
init 1
y
init 2

即使将xy设为最终值也不会影响这一点,因为它们仍然不是编译时常数。

p。S: 还注意到,只有当我插入最后一个修饰符时,字符串变量初始化才会发生在块之前。

在这一点上,它是一个编译时常数,对它的任何使用基本上都是内联的。此外,变量值在其他初始化程序之前赋值,如上所述。

JLS的第15.28节定义了编译时常数——它包括所有基元值和String,但而不是包装器类型,如Integer

这里有一个简单明了的问题答案。。。。

static Variable:

静态变量在JVM加载Class时执行,而Class实例化或其static method被调用时加载。

static Block or static Initializer Block:

static 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();
}
}

以上内容将打印static 1

原因是JVM将执行优化过程,即Constant folding,对常量变量进行预计算。

此外,在的情况下,结果static null,因为Constant folding应用于Primitive类型,而不是Wrapper对象,在您的情况下是它的Integer。。。

它们按给定顺序初始化(字段和静态块),这就是为什么打印值为null,没有为静态块之后定义的静态字段分配任何内容。

最新更新