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

Java 类中静态块和静态变量的执行顺序是什么?,java,static,final,Java,Static,Final,可能重复: 为什么在初始化块中更新字符串变量而不是整数(即使先写入块) 我的输出是 static null 注意,字符串变量初始化只在我插入最后一个修饰符时发生在块之前。为什么会这样?为什么整数也不这样呢?我也将其声明为final static(最终静态)它们是按给定顺序初始化的(字段和静态块),这就是为什么打印值为null,在静态块之后定义的静态字段没有分配任何内容。它们是按给定顺序初始化的(字段和静态块),这就是为什么打印值为空的原因,没有为静态块后定义的静态字段分配任何内容。从JLS的

可能重复:

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

我的输出是

static null

注意,字符串变量初始化只在我插入最后一个修饰符时发生在块之前。为什么会这样?为什么整数也不这样呢?我也将其声明为final static(最终静态)

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

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

从JLS的

初始化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
即使将
x
y
设为final也不会影响这一点,因为它们仍然不是编译时常量

注意,字符串变量初始化只在我插入最后一个修饰符时发生在块之前

在这一点上,它是一个编译时常量,它的任何用法基本上都是内联的

JLS的定义编译时常量-它包括所有原语值和
字符串
,但不包括JLS的
整型
等包装类型,它们被适当地截断:

初始化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
即使将
x
y
设为final也不会影响这一点,因为它们仍然不是编译时常量

注意,字符串变量初始化只在我插入最后一个修饰符时发生在块之前

在这一点上,它是一个编译时常量,它的任何用法基本上都是内联的


JLS的定义编译时常量-它包括所有原语值和
字符串
,但不包括包装器类型,如
整数

,下面是对您问题的简短而直接的回答

静态变量

JVM
加载
时,执行静态变量;当调用
类的实例化或其
静态方法
时,加载

静态块或静态初始值设定项块

静态初始化程序块在调用其
静态方法
之前被初始化
类在调用其
静态方法
之前被实例化,甚至在使用其
静态变量
之前被初始化

///Edited Part/////strong>

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

}
以上内容将打印
静态1

原因是
JVM
将执行名为
常量折叠的优化过程,对常量变量进行预计算


此外,在您的案例中,结果是
静态空值
原因
常量折叠
应用于原语类型,而不是包装器对象,在您的案例中是它的整数…

这里是对您的问题的简短而直接的回答

静态变量

JVM
加载
时,执行静态变量;当调用
类的实例化或其
静态方法
时,加载

静态块或静态初始值设定项块

静态初始化程序块在调用其
静态方法
之前被初始化
类在调用其
静态方法
之前被实例化,甚至在使用其
静态变量
之前被初始化

///Edited Part/////strong>

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

}
以上内容将打印
静态1

原因是
JVM
将执行名为
常量折叠的优化过程,对常量变量进行预计算

此外,在您的情况下,的结果是
静态null
原因
常量折叠
应用于原语类型,而不是包装器对象,在您的情况下,它是