在下面的代码中,使用类名访问静态变量时,它不会引发前向引用错误,但是在不使用类名的情况下访问它会抛出正向引用错误。
为什么使用类名访问时不会发生这种情况?
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中定义:
有时会限制使用声明后在文本上出现的类变量,即使这些类变量在范围内(第6.3节)。具体来说,如果满足以下所有条件,则是编译时错误:
使用类变量后,将在文本或类C中声明类变量;
在C的类变量初始值设定项或C的静态初始值设定项中,此名称是一个简单的名称;
用法不在作业的左侧;
C是封闭使用的最里面的类或接口。
因此,基本上,您的first Sysout()
满足以上所有四个条件,因此是编译时错误。
在2nd中Sysout()
,您将a
使用它的限定名称(而不是简单名称)进行访问,根据上面的规则,该名称是允许的。
现在,这样做的原因是,当您访问时Test.a
,编译器将确保Test
已加载类并且所有static
字段均已初始化,因此它可以访问field
a
。但是在访问a
简单名称时,编译器不确定的初始化html" target="_blank">程序a
是否已经运行,因为它可能仍在加载类中。
考虑以下加载类的过程:
static
声明的所有变量分配内存。至此,变量a
已经分配了内存(声明已完成)static
初始化程序都按照出现的顺序运行。
Sysout(a);
。a
尚未初始化,因此您无法访问它。(错误)a = 99
。在这里,您实际上是在初始化变量a
。很好。Sysout(Test.a)
-理由已经在上面发布。编译器知道Test
已经加载。static int a = 10
执行。它重新初始化a
为10
。记住,声明部分已经在第一步中得到了照顾。无论我怎么努力,我都会遇到这个问题。我尽了我所能。声明State类的对象时,显示错误“非静态变量,无法从静态上下文引用”
问题内容: java为什么不能从静态环境引用非静态变量? 问题答案: 你必须了解一个类与该类实例之间的区别。如果你在街上看到汽车,即使你看不到哪种型号或类型,也将立即知道它是汽车。这是因为你将看到的与“汽车” 类进行了比较。该类包含与所有汽车相似的类。可以将其视为模板或想法。 同时,你看到的汽车是“汽车”类的一个实例,因为它具有你期望的所有属性:有人驾驶它,它有引擎,车轮。 因此,该班级说“所有汽
问题内容: 我有一个非常简单的类,想用作另一个类的子类。但是,当我将其代码放入父类时,我得到: 非静态变量,不能从静态上下文中引用 另一方面,当我将sublass 的类代码放在“父母的”类代码之外时,我不会收到此错误。 为什么会这样呢? 问题答案: 嵌套类(顺便说一下,它 不是 子类)没有被标记为静态的,因此它是一个 内部 类,需要构造一个编码类(JavaApp1)的实例。 选项: 使嵌套类静态
问题内容: 我试图编译其中一个Java类与拒绝 非法向前引用 错误,其中有问题的参考是词汇 后 的基准场。在显示相同行为时,将尽可能精简以下类: 并且的许多用途仅用作占位符,以删除不相关的代码段。 使用编译时,javac会显示以下错误消息: 因此,编译器抱怨的声明引用,而应在的声明范围内。但是,一旦删除了in 的声明的引用(例如,通过将第5行从更改为),编译器将接受该类。 如何解释呢?我对 前锋的
可能重复: 不能从静态上下文(java)引用非静态变量 即使在这种情况下,我们也试图从静态方法访问非静态类。但这不会给出任何错误。为什么?
我有一个非常简单的类,我想用它作为另一个类的子类。但当我将其代码放入父类时,我得到: 非静态变量,不能从静态上下文中引用 另一方面,当我将子类GenTest的类代码放在“父类”的类代码之外时,我没有得到这个错误。 为什么会发生这种情况?