Java 哪些情况允许在静态初始值设定项块中进行前向引用?

Java 哪些情况允许在静态初始值设定项块中进行前向引用?,java,class,static,initialization,declaration,Java,Class,Static,Initialization,Declaration,在Java中,静态变量的初始化是按文本顺序执行的。因此,在清除静态变量之前,不可能访问静态变量,例如静态初始值设定项块中的静态变量 但是,我注意到,在声明静态变量之前,可以访问它 给定以下代码: 静态{ 静态=真; } 公共静态布尔静态=false; 公共静态void main(字符串[]args){ 系统输出打印项次(静态); } 人们可能认为静态初始值设定项块中存在编译错误(static=true;),但实际上编译很好。此外,程序的输出为false。我希望它是true,因为我在静态初始值设

在Java中,静态变量的初始化是按文本顺序执行的。因此,在清除静态变量之前,不可能访问静态变量,例如静态初始值设定项块中的静态变量

但是,我注意到,在声明静态变量之前,可以访问它

给定以下代码:

静态{
静态=真;
}
公共静态布尔静态=false;
公共静态void main(字符串[]args){
系统输出打印项次(静态);
}
人们可能认为静态初始值设定项块中存在编译错误(
static=true;
),但实际上编译很好。此外,程序的输出为
false
。我希望它是
true
,因为我在静态初始值设定项中为它赋值

  • 为什么此代码段不是编译错误,为什么初始化后变量未设置为
    true
  • 在哪些情况下(通常)可以在Java中转发访问静态变量
为什么此代码段不是编译错误,为什么初始化后变量未设置为true? 如果在赋值语句的左侧使用,Java允许向前引用静态变量。初始化后该值为
false
的原因是,当Java到达静态初始化程序块时,变量
static
已经声明(发生在类的实际初始化之前),并且最初设置为
false
(默认值)。在静态初始值设定项之后,声明行上的赋值仍将执行,并且该值将以
false
结束

在哪些情况下(通常)可以在Java中转发访问静态变量? Java 8的Java语言规范(JLS)规定:

静态初始值设定项和类变量初始值设定项是 以文本顺序执行可能不引用类变量 在其声明出现的类中声明 即使这些类变量在 范围(§8.3.3)

一般来说,如上所述,不允许正向引用。但也有以下所述的某些例外情况:

8.3.3。在字段初始化期间转发引用

使用声明以文本形式出现的类变量 使用后有时会受到限制,即使这些类 变量在范围内(§6.3)。具体来说,这是一个编译时 如果以下所有条件均为真,则出现错误:

类或接口C中类变量的声明 在使用类变量后以文本形式显示 是C或a类变量初始值设定项中的简单名称 C的静态初始值设定项不在左侧使用 C是最里面的类或接口 附上使用说明 为了说明这些条件,我创建了类
ThisClass
,并为每个条件创建了一个示例。如果这四个条件中只有一个是false,那就不是编译错误


1。类或接口C中的类变量声明在使用类变量后以文本形式出现

public static boolean STATIC1=false;
静止的{
如果(!STATIC1){
System.out.println(“将STATIC1设置为true”);
STATIC1=真;
}
}
STATIC1
的用法在定义之后出现。违反了编译器错误的最基本条件。如您所料,初始化后的
STATIC1
值为
true


2。在类变量初始值设定项C或静态初始值设定项C中使用的是一个简单的名称

静态{
如果(!ThisClass.STATIC2){
System.out.println(“将STATIC2设置为true”);
ThisClass.STATIC2=true;
}
}
公共静态布尔STATIC2=false;
现在满足了第一个条件,但违反了第二个条件。我们使用限定名(而不是简单名)访问变量
STATIC2
。JLS中描述了不同之处,如:

名称有两种形式:简单名称和限定名称。
A 简单名称是单个标识符。
限定名称 由名称、“.”标记和标识符组成

更有趣的是,初始化过程中实际发生了什么。在静态初始值设定项的第一行,通过类限定符读取
STATIC2
的值。此时(由于类是按文本顺序初始化的),变量
STATIC2
尚未初始化。在这种情况下,将使用默认值,
boolean
的默认值为
false
。输入
if
块,并且
STATIC2
的值设置为
true
。继续初始化,并将
STATIC2
再次设置为
false
,这是变量在初始化后将处于的状态

注意:为了证明
true
的赋值确实发生了,您可以尝试以下方法:

静态{
如果(!ThisClass.STATIC2a){
System.out.println(“将STATIC2a设置为true”);
ThisClass.STATIC2a=真;
}
}
公共静态布尔STATIC2a;
此代码编译得非常好,初始化结束时的
STATIC2a
值将为
true
!最后一行代码甚至可以替换为以下奇怪的语句,这进一步澄清了正在发生的事情:

public static boolean STATIC2a=ThisClass.STATIC2a;

3。该用法不在作业的左侧

静态{
System.out.println(“将STATIC3设置为true”);
STATIC3=tru