gpt4 book ai didi

java - 为什么在使用带有类名的静态变量时不显示非法前向引用错误

转载 作者:行者123 更新时间:2023-12-05 07:49:16 25 4
gpt4 key购买 nike

在下面的代码中,当访问带有类名的静态变量时,它不会抛出前向引用错误,但在没有类名的情况下访问它会抛出前向引用错误。

为什么使用类名访问时不会发生这种情况?

class Test{
static {
System.out.println(a); // shows error
a = 99; // and this line too doesn't give error
System.out.println(Test.a); // this line doesn't
}
static int a = 10;
static{
System.out.println(a);
}
}

最佳答案

前向引用规则在JLS §8.3.3中定义:

Use of class variables whose declarations appear textually after the use is sometimes restricted, even though these class variables are in scope (§6.3). Specifically, it is a compile-time error if all of the following are true:

  • The declaration of a class variable in a class or interface C appears textually after a use of the class variable;

  • The use is a simple name in either a class variable initializer of C or a static initializer of C;

  • The use is not on the left hand side of an assignment;

  • C is the innermost class or interface enclosing the use.

所以,基本上是您的第一个 Sysout() , 满足以上 4 个条件,因此是编译时错误。

在第二个Sysout() ,您正在访问 a使用它的限定名称,而不是简单名称,根据上述规则,这是允许的。

现在,这样做的原因是,当您访问 Test.a 时, 编译器确定 Test类已加载并且所有 static字段已经初始化,所以它可以访问字段a .但是在访问 a 时在简单名称上,编译器不确定 a 的初始化程序是否已经运行,因为它可能仍在加载类。

考虑以下加载类的过程:

  • 加载类时,为所有 static 分配内存其中声明的变量。此时,变量a已分配内存(声明完成)
  • 然后所有static初始化程序按出现顺序运行。
    • 第一个语句是 Sysout(a); . a还没有初始化,所以你不能访问它。 (错误)
    • 第二条语句是a = 99 .这里你实际上是在初始化变量 a .非常好。
    • 第三个是 Sysout(Test.a) - 上面已经发布了对此的推理。编译器知道 Test已经加载。
    • 然后 static int a = 10被执行。它重新初始化 a10 .请记住,声明部分已在第一步中完成。

关于java - 为什么在使用带有类名的静态变量时不显示非法前向引用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37554965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com