为什么java中构造函数/静态初始值设定项/静态成员函数的顺序如此奇怪?
运行之后,下面是打印的顺序: 主要起点 建造师 静态初始化 多诺丁酒店 为什么调用DataFactory.doNothing()会触发构造函数? 为什么构造函数要在静态初始值设定项之前运行?下面是构造函数的配置: 构造函数由类实例创建表达式调用(§15.9) 以及静态块的: 初始化类时,将执行类中声明的静态初始值设定项(§12.4.2)为什么java中构造函数/静态初始值设定项/静态成员函数的顺序如此奇怪?,java,constructor,static-methods,static-members,Java,Constructor,Static Methods,Static Members,运行之后,下面是打印的顺序: 主要起点 建造师 静态初始化 多诺丁酒店 为什么调用DataFactory.doNothing()会触发构造函数? 为什么构造函数要在静态初始值设定项之前运行?下面是构造函数的配置: 构造函数由类实例创建表达式调用(§15.9) 以及静态块的: 初始化类时,将执行类中声明的静态初始值设定项(§12.4.2) 正如您所见,在初始化类时首先调用构造函数,然后在调用构造函数之后立即调用静态块。它正在调用构造函数,因为您正在同一数据工厂中创建数据工厂的实例;因此,它需要调用
正如您所见,在初始化类时首先调用构造函数,然后在调用构造函数之后立即调用静态块。它正在调用构造函数,因为您正在同一
数据工厂中创建数据工厂的实例;因此,它需要调用构造函数一次,以便能够实例化它。注释或删除私有静态数据工厂ourInstance=new DataFactory()代码>行,构造函数调用不会发生
类初始化后立即执行静态初始值设定项。很抱歉告诉您,Rod_Algonquin不完整,而且也是机器。正确答案是:
“静态初始化块在类首次加载时运行”
因此,您可以问“为什么构造函数在静态之前运行?!”
怎么可能?还有一个初始化块的规则(静态和实例)
初始化块在类中出现的顺序很重要
只需将静态初始化块的顺序切换到静态实例化,即可查看发生了什么:
public class DataFactory {
private static DataFactory ourInstance = new DataFactory();
static {
System.out.println("static initialize");
}
private DataFactory() {
System.out.println("constructor");
}
public static void doNothing() {
System.out.println("inside doNothing");
}
}
public class App {
public static void main(String[] args) {
System.out.println("main start");
DataFactory.doNothing();
}
输出:
主要起点
静态初始化
建造师
初始化类时,在doNothing内部,它将按照它们在代码中出现的顺序执行所有的静态{…}
和静态字段初始值设定项(请参见,尤其是步骤列表中的步骤9)。在您的示例中,有两个这样的初始值设定项:
private static DataFactory-ourInstance=new DataFactory()代码>
静态{…}
块
所以,第一个先发生。它实例化一个对象并将其引用分配给ourInstance
。要实例化对象,它需要调用构造函数,正如您所看到的那样
完成后,执行静态块,打印“静态初始化”
此时,类被初始化,并且方法doNothing
最终可以被调用。静态字段初始化调用构造函数
最后,初始化字段“ourInstance”的代码也是静态初始化器的一部分
因此,实际发生的是:
public class DataFactory {
static { //// SWAPPED HERE
System.out.println("static initialize");
}
///// SWAPPED HERE
private static DataFactory ourInstance = new DataFactory();
private DataFactory() {
System.out.println("constructor");
}
public static void doNothing() {
System.out.println("inside doNothing");
}
}
否,加载类时将执行静态初始值设定项。实例化类时执行的是非静态初始值设定项这应该有助于它的运行,因为private static DataFactory ourInstance=new DataFactory()代码>行。。。
public class DataFactory {
private static DataFactory ourInstance;
static {
outInstance = new DataFactory(); // 2
System.out.println("static initialize"); // 4
}
private DataFactory() {
System.out.println("constructor"); // 3
}
public static void doNothing() {
System.out.println("inside doNothing"); // 6
}
}
public class App {
public static void main(String[] args) {
System.out.println("main start"); // 0
DataFactory.doNothing(); // 1 (static init) and 5 (method call)
}
}