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

2022-09-03 00:53:35

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

P.S:还注意到字符串变量初始化仅在我插入最终修饰符时才发生在块之前。为什么是这样?为什么不是整数呢?我也已将其声明为最终静态


答案 1

从 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 节定义了编译时常量 - 它包括所有基元值和 ,但不包括包装器类型,例如 。StringInteger


答案 2

这是一个简短而直接的答案,给你的问题....

static Variable:

静态变量在加载 时执行,在实例化或调用时加载JVMClassClassstatic method

static Block or static Initializer Block:

静态静态初始值设定项块在实例化之前或调用它之前甚至在使用它之前进行初始化。Classstatic methodstatic 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

原因是 will 会做一个称为 优化过程,对常量变量进行预计算。JVMConstant folding

此外,在你的情况下,结果是原因应用于基元类型而不是包装器对象,在你的情况下,它的整数...static nullConstant folding


推荐