只执行一次
复制:
可以添加到学生类的构造函数中,例如:
运行时会发现只打印一次
大致原理:
静态变量是类变量,第一次使用类时只初始化一次。类装入器中会有一个锁,以防止类被多次初始化。静态字段和静态代码块只执行一次。从编译器的角度来看,编译时编译器会按顺序收集静态字段和静态代码块,然后将其放入生成的<cinit>特殊方法中,初始化类时会调用<cinit>方法。
应用程序:
对于您的问题:
在前一个线程初始化之后,判断它是否已成功初始化,并直接获取结果
您的问题有点有趣。前一个线程的初始化可以说是取锁,然后执行锁代码。当锁退出时,锁代码的结果将完全同步,这是锁的一个特性(比如内存可见性)。然后下一个字段结果就是正常结果
静态int只初始化一次,但可以多次修改。静态变量属于静态存储模式。它的存储空间是内存中的静态数据区。在程序运行期间,此区域中的数据一直占用这些存储空间。
静态变量是静态的,因为它的地址在程序的整个生命周期中都是静态的。也就是说,整个程序只保留一个副本。static关键字允许它在不同的函数调用之间保持其值。如果静态变量的值在被访问后发生变化,它将保留新值。如果再次访问该变量,它将保持最新的值classa{公共:私人:}inta::i=1//类的静态变量必须用这种方式初始化。类成员函数的静态变量只能在该函数中使用。
两者都在程序的数据区和全局变量区生成。
如果我们不考虑父类,我们可以先进行静态初始化,然后进行非静态初始化。
静态初始化包括静态成员变量和静态块的初始化。实际上,静态块在编译期间是集中的。
非静态初始化包括非静态成员变量初始化、非静态块和构造方法,编译后集中在构造方法中。
如果没有相互通话,那就非常简单了。首先,静态初始化。如果在静态初始化过程中调用了后者呢?!你可以编写一个代码来测试它:
输出:
你可以先看到它确实是静态初始化,但是中间有对构造方法的调用。
虽然编译器不报告错误,但此调用实际上是有风险的。
由于静态成员变量(如果已设置)在初始化之前调用类构造函数(假设存在依赖关系),因此该过程实际上是不可控制的。
看看这个例子:你能想象这种输出吗?
因此,如果必须在静态初始化过程中调用此类的构造函数。
一定要注意初始化顺序,准确到语句。