考虑以下情况:
的码:1
public class StaticDemo {
static{
b=5;
System.out.println("Static B:"+b);/*Compilation error:"Cannot reference a field before it is defined"*/
}
static int b;
static{
System.out.println("B:"+b);
}
public static void main(String[] args) {
}
}
如下所示注释代码,没有错误,并且显示了以下输出 的码:2
public class StaticDemo {
static{
b=5;
//System.out.println("Static B:"+b);
}
static int b;
static{
System.out.println("B:"+b);
}
public static void main(String[] args) {
}
}
输出 -
B:5
如果执行基于静态变量或块的写入顺序。
为什么初始化不会引发编译错误(b=5
)
如代码所示:2。
还请解释为什么错误被抛出代码:1,如果 代码:2是真的吗?
答案 0 :(得分:3)
来自Java Language Specification §8.3.2.3
成员声明只有在成员是类或接口C的实例(分别是静态)字段并且满足以下所有条件时才需要以文本方式显示:
- 用法发生在C的实例(分别是静态)变量初始化程序或C的实例(分别是静态)初始化程序中。
- 用法不在作业的左侧。
- 使用方法是一个简单的名称。
- C是封闭用法的最里面的类或接口。
如果不满足上述四项要求中的任何一项,则为编译时错误。
[...]
上述限制旨在在编译时捕获循环或其他格式错误的初始化
换句话说,可以写到稍后在类中声明的字段,但不能从读取。
在我引用的部分之后的示例框中有更详细的示例。
答案 1 :(得分:2)
在第一个示例中,变量b
由第一个静态块初始化,第一个静态块是第一个要执行的静态块。编译器不记得第一行,因此在静态块的第二行,它抱怨引用b
,因为'b'可能尚未初始化。
当编译器通过b
的定义时,他确信b
已初始化。因此,您的代码可以引用/访问它。
在源代码中发生之前初始化静态变量很好,但只有在它发生之后才允许访问它。
如果您查阅Java Specification,请说明以下内容:
Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class.
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
1) A static field declared by T is assigned.
2) A static field declared by T is used and the field is not a constant variable (§4.12.4).
1)说,在直接分配静态字段之前执行静态初始化程序。 2)说,在使用字段之前,必须执行初始化程序(块和字段初始化程序)。
因此,您可以为静态初始化程序块中的静态字段分配值,但在完成所有初始化之前无法使用它。这就是我理解它的方式。
答案 2 :(得分:-1)
执行顺序是从上到下。在声明之前,不能使用静态字段。
为什么错误被抛出代码:1,如果代码:2为真
您尝试在声明变量之前使用变量。 BTW没有在运行时抛出错误。这是编译器错误。