java - 在 Java 中使用 static 关键字创建对象

标签 java static initialization

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/

相关文章:

java - 访问网络路径中的文件

java - 匿名类作为泛型参数

C++ 事件处理 - const 问题

javascript:如何访问静态属性

c - 将指定的初始值设定项与未命名的嵌套数据类型一起使用

c++ - 默认初始化类成员总是可取的吗?

java - 使用 ByteBuddy 在同一个类中检测多个方法

java - 如何从回收者 View 适配器获取项目

java - 调用EJB中静态实例的方法

javascript - 在javascript中初始化 'multidimensional'对象