java类中的静态变量是什么时候初始化的_关于Java:何时初始化静态变量?

我想知道何时将静态变量初始化为其默认值。

加载类时是否创建(分配)了静态var是否正确,

然后执行静态初始化程序和声明中的初始化?

在什么时候给出默认值? 这导致前向参考的问题。

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

请您编辑您的问题以包括您所引用的报价。

您阅读过Java语言规范吗? 故意如此,这是一个易于阅读的文档。 如果您已阅读该书,则可能了解发生了什么。 如果没有,您至少可以问一个更具体的问题...

我认为此问答是stackoverflow.com/questions/3499214的一个重复说明。

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

It is a variable which belongs to the class and not to object(instance)

Static variables are initialized only once , at the start of the execution. These variables will be initialized first, before the initialization of any instance variables

A single copy to be shared by all instances of the class

A static variable can be accessed directly by the class name and doesn’t need any object.

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

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

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

An inner class is a nested class that is not explicitly or implicitly

declared static.

...

Inner classes may not declare static initializers (§8.7) or member interfaces...

Inner classes may not declare static members, unless they are constant variables...

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

Java中的final字段可以与其声明位置分开进行初始化,但这不适用于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变量只有一个副本,而不是与实例变量相关联的与该类型的每个实例相关联的副本,并且如果我们尝试在构造函数中初始化类型为static final的z ,它将尝试重新初始化static final类型的字段z,因为构造函数是在类的每个实例上运行的,而静态final字段上不得出现该实例。

In case of static inner classes, they can not have static fields似乎是一个错字。内部类是非静态的。

您应该使用但是而不是

当您启动JVM并首次加载类时(这是通过以任何方式首次引用该类时由类加载器完成的操作),所有静态块或字段都将加载到JVM中并可以访问。

不幸的是,这个答案在初始化静态变量时包含一些事实上的错误。请参阅stackoverflow.com/a/3499322/139985。

看到:

JLS 8.7,静态初始化程序

JLS 12.2,加载类和接口

JLS 12.4,类和接口的初始化

最后一个特别提供了详细的初始化步骤,这些步骤详细说明了何时初始化静态变量以及初始化的顺序(请注意,final类变量和作为编译时常量的接口字段首先被初始化。)

我不确定您对第3点的具体问题是什么(假设您是说嵌套的?)。详细序列说明这将是递归初始化请求,因此它将继续初始化。

当类加载器加载该类时,将初始化静态字段。此时将分配默认值。按照它们在源代码中出现的顺序进行操作。

初始化的顺序为:

静态初始化块

实例初始化块

建设者

JVM规范文档中说明了该过程的详细信息。

从另一个问题的代码开始:

class MyClass {

private static MyClass myClass = new MyClass();

private static final Object obj = new Object();

public MyClass() {

System.out.println(obj); // will print null once

}

}

对该类的引用将开始初始化。首先,该类将被标记为已初始化。然后,将使用MyClass()的新实例初始化第一个静态字段。请注意,立即为myClass提供了对空白MyClass实例的引用。有空格,但是所有值都为空。现在将执行构造函数并显示obj,该值为null。

现在回到初始化类:obj被引用为一个新的真实对象,我们完成了。

如果通过以下语句取消了此设置:MyClass mc = new MyClass();将为新的MyClass实例分配空间(并将引用放置在mc中)。构造函数将再次执行,并再次打印obj,现在它不为null。

真正的窍门是,当您使用new时(如在WhatEverItIs weii = new WhatEverItIs( p1, p2 ); weii中一样),将立即获得对一些空内存的引用。然后,JVM将继续初始化值并运行构造函数。但是,如果您以某种方式引用weii之前(例如,通过另一个线程进行引用或通过类初始化进行引用),则您正在查看的是填充有空值的类实例。

在初始化完成之前,不会将类标记为已初始化-否则将没有任何意义。标记为已初始化几乎是最后一步。参见JLS 12.4.2。

@DaveNewton:一旦有人引用了该类并开始对其进行初始化,则所有其他引用将把该类视为已初始化。他们不会尝试初始化它,也不会等待它被初始化。因此,从程序开始看似非空的字段实际上可以在一段时间内为空。不理解这是造成所有混乱的原因。我认为最简单的说法是,未初始化的类在第一个引用上被"标记"为已初始化,所有其他引用都将其视为已初始化,这就是为什么会发生这种情况。

对先前注释的更正:如Dave Newtons JLS 12.4.2所述,该类在初始化时被锁定。其他线程将等待该类被初始化。但是,这并不影响这种情况,它们都在一个线程中发生。

静态变量可以通过以下三种方式初始化,如下所示,选择任意一种

您可以在声明时将其初始化

或者您可以通过制作静态块来实现,例如:

static {

// whatever code is needed for initialization goes here

}

静态块有替代方法-您可以编写私有的静态方法

class name {

public static varType myVar = initializeVar();

private static varType initializeVar() {

// initialization code goes here

}

}

静态变量

它是一个属于类而不属于对象(实例)的变量

静态变量仅在执行开始时初始化一次(当Classloader首次加载类时)。

在初始化任何实例变量之前,将首先初始化这些变量

该类的所有实例共享一个副本

可以通过类名称直接访问静态变量,并且不需要任何对象

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

三疯兰尼斯特

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值