class abc {
int a = 0;
static int b;
static abc h = new abc(); //line 4
public abc() {
System.out.println("cons");
}
{
System.out.println("ini");
}
static {
System.out.println("stat");
}
}
public class ques {
public static void main(String[] args) {
System.out.println(new abc().a);
}
}
当我编写这段代码时,我得到的输出顺序如下:
ini
cons
stat
ini
cons
0
在这里,当我在 main() 中创建一个新对象时,类 abc
被加载并且 static
变量和 block 按照它们被写入的顺序执行。当控制来到第 4 行时,调用 static abc h = new abc();
实例初始化 block 。为什么?为什么在第 4 行创建新对象时不调用静态 block ,并且直到那时静态 block 也没有被调用一次,所以根据惯例应该调用静态 block 。为什么会出现这种意想不到的输出?
最佳答案
JLS says :
The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (§8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.
这正是您的情况。
这是您的原始示例:http://ideone.com/pIevbX - abc
的静态初始化器 在 abc
的静态实例被赋值后 - 所以静态初始化器无法执行 - 它是在静态变量初始化之后的文本
让我们将第 4 行移动到 静态初始化 block 之后 - http://ideone.com/Em7nC1 :
class abc{
int a = 0;
static int b;
public abc() {
System.out.println("cons");
}
{
System.out.println("ini");
}
static {
System.out.println("stat");
}
static abc h = new abc();//former line 4
}
现在你可以看到如下输出:
stat
ini
cons
ini
cons
0
现在初始化顺序更符合您的预期 - 首先调用静态初始化器,然后 abc
的静态实例以通用方式初始化。
关于java - 在 Java 中使用 static 关键字创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24927401/