在什么样的顺序在一个类的静态块和静态变量执行? [重复](in what order are s

2019-06-18 04:30发布

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

PS:也注意到,字符串变量初始化只有当我插入final修饰符块之前发生。 这是为什么?为什么不为整数呢?我已经宣布它作为最后的静态太

Answer 1:

从第12.4.2节的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

甚至连做xy最终不会影响这个在这里,因为他们仍然不会是编译时间常数。

PS:也注意到,字符串变量初始化只有当我插入final修饰符块之前发生。

在这一点上,它是一个编译时间常数,它的任何用途基本上内联。 此外,可变值是初始值设定的其余部分之前分配,如上所述。

部15.28的JLS限定编译时间常数-它包括所有的原始值和String ,但不是包装类型如Integer



Answer 2:

这是一个短期和直接的回答你的问题....

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

}

以上将打印 static 1

其原因是, JVM将做称为优化过程 Constant folding ,在做常数变量的预先计算。

此外,在你的情况下,结果static null原因Constant folding应用于原始类型,而不是包装对象,在你的情况下,其整...



Answer 3:

它们在给定的顺序(字段和静态块)初始化,这就是为什么印刷值为null ,没有被分配到那些静态块之后定义静态字段。



文章来源: in what order are static blocks and static variables in a class executed? [duplicate]