Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java中构造函数/静态初始值设定项/静态成员函数的顺序如此奇怪?_Java_Constructor_Static Methods_Static Members - Fatal编程技术网

为什么java中构造函数/静态初始值设定项/静态成员函数的顺序如此奇怪?

为什么java中构造函数/静态初始值设定项/静态成员函数的顺序如此奇怪?,java,constructor,static-methods,static-members,Java,Constructor,Static Methods,Static Members,运行之后,下面是打印的顺序: 主要起点 建造师 静态初始化 多诺丁酒店 为什么调用DataFactory.doNothing()会触发构造函数? 为什么构造函数要在静态初始值设定项之前运行?下面是构造函数的配置: 构造函数由类实例创建表达式调用(§15.9) 以及静态块的: 初始化类时,将执行类中声明的静态初始值设定项(§12.4.2) 正如您所见,在初始化类时首先调用构造函数,然后在调用构造函数之后立即调用静态块。它正在调用构造函数,因为您正在同一数据工厂中创建数据工厂的实例;因此,它需要调用

运行之后,下面是打印的顺序:

主要起点

建造师

静态初始化

多诺丁酒店

为什么调用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)
      }
    }