一尘不染

Java 静态变量何时初始化?

java

我想知道静态变量何时初始化为其默认值。加载类时,先创建(分配)静态变量,然后执行静态初始化程序和声明中的初始化是否正确?在什么时候给出默认值?这导致前向参考的问题。

另外,如果你可以参考“ 为什么没有及时初始化静态字段?”这一问题进行解释,尤其是Kevin Brock在同一网站上给出的答案。我不明白第三点。


阅读 976

收藏
2020-03-09

共1个答案

一尘不染

从请参阅Java静态变量方法:

  • 它是一个属于类而不属于对象(实例)的变量
  • 静态变量在执行开始时仅初始化一次。在初始化任何实例变量之前,将首先初始化这些变量
  • 该类的所有实例共享一个副本
  • 静态变量可以通过类名直接访问,不需要任何对象。

如果你没有故意将实例和类(静态)变量初始化为标准默认值,则将它们自动初始化为标准默认值。尽管不会自动初始化局部变量,但是在使用局部变量之前,你无法编译无法初始化局部变量或为该局部变量赋值的程序。

编译器实际上所做的是内部生成一个单一的类初始化例程,该例程将所有静态变量初始化器和所有静态初始化器代码块按它们在类声明中出现的顺序组合在一起。第一次加载类时,仅一次自动运行一次初始化过程。

对于内部类,它们不能具有静态字段

一个内部类是没有明确或隐含声明的嵌套类static

内部类不能声明静态初始化器(第8.7节)或成员接口。

内部类不能声明静态成员,除非它们是常量变量。

请参见JLS 8.1.3内部类和封闭实例

finalJava中的字段可以与声明位置分开进行初始化,但这不适用于static final字段。请参见下面的示例。

final class Demo
{
    private final int x;
    private static final int z;  //must be initialized here.

    static 
    {
        z = 10;  //It can be initialized here.
    }

    public Demo(int x)
    {
        this.x=x;  //This is possible.
        //z=15; compiler-error - can not assign a value to a final variable z
    }
}

这是因为与该类型关联的变量只有一个副本static,而不是与实例变量一样与该类型的每个实例关联的副本,并且如果我们尝试在构造函数中初始化z类型static final,它将尝试重新初始化static final类型字段z因为构造函数是在类的每个实例化上运行的,该实例化不能在静态final字段中发生。

2020-03-09