静态变量什么时候初始化?

2022-01-18 00:00:00 initialization static java

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

I am wondering when static variables are initialized to their default values. Is it correct that when a class is loaded, static vars are created (allocated), then static initializers and initializations in declarations are executed? At what point are the default values are given? This leads to the problem of forward reference.

如果您可以参考 为什么没有及时初始化静态字段? 尤其是 Kevin Brock 在同一站点上给出的答案.第三点看不懂.

Also please if you can explain this in reference to the question asked on Why static fields are not initialized in time? and especially the answer given by Kevin Brock on the same site. I can't understand the 3rd point.

推荐答案

来自 查看Java 静态变量方法:

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

如果您未能有意初始化实例和类(静态)变量,它们将自动初始化为标准默认值.虽然局部变量不会自动初始化,但您不能编译无法初始化局部变量或在使用之前为该局部变量赋值的程序.

Instance and class (static) variables are automatically initialized to standard default values if you fail to purposely initialize them. Although local variables are not automatically initialized, you cannot compile a program that fails to either initialize a local variable or assign a value to that local variable before it is used.

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

What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.

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

In case of inner classes, they can not have static fields

一个内部类是一个不显式或隐式的嵌套类声明 static.

An inner class is a nested class that is not explicitly or implicitly declared static.

...

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

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

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

final 字段可以独立于它们的声明位置进行初始化,但这不适用于 static final 字段.请参阅下面的示例.

final fields in Java can be initialized separately from their declaration place this is however can not be applicable to static final fields. See the example below.

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

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

This is because there is just one copy of the static variables associated with the type, rather than one associated with each instance of the type as with instance variables and if we try to initialize z of type static final within the constructor, it will attempt to reinitialize the static final type field z because the constructor is run on each instantiation of the class that must not occur to static final fields.

相关文章