gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 13:09:42 24 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 的初始化程序是否已经运行,因为它可能仍在加载类的过程中。

考虑以下类加载过程:

  • 加载类时,将为其中声明的所有静态变量分配内存。此时,变量a已经分配了内存(声明完成)
  • 然后所有static初始化器按照出现的顺序运行。
    • 第一个语句是 Sysout(a);a 尚未初始化,因此您无法访问它。 (错误)
    • 第二条语句是a = 99。这里实际上是在初始化变量a。完全没问题。
    • 第三个是 Sysout(Test.a) - 其原因已在上面发布。编译器知道 Test 已加载。
    • 然后执行static int a = 10。它将 a 重新初始化为 10。请记住,声明部分已在第一步中处理完毕。

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

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