关于Java静态变量初始化的问题

源代码:

class Bowl {
    Bowl(int i) {
        System.out.println("Bowl(" + i + ")");
    }  //构造器

    void f1(int i) {
        System.out.println("f1(" + i + ")");
    }
}

class Table {
    static Bowl bowl1 = new Bowl(1);  //2、加载Bowl类

    Table() {
        System.out.println("Table()");
        bowl2.f1(1);
    }

    void f2(int i) {
        System.out.println("f2(" + i + ")");
    }

    static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);

    Cupboard() {
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }

    void f3(int i) {
        System.out.println("f3(" + i + ")");
    }

    static Bowl bowl5 = new Bowl(5);
}

public class StaticInitialization {
    public static void main(String[] args) {
        System.out.println("new Cupboard() in main");
        new Cupboard();
        System.out.println("new Cupboard() in main");
        new Cupboard();   // 创建Cupboard()实例,不进行类加载(每个类只加载一次
        table.f2(1);
        cupboard.f3(1);
    }

    static Table table = new Table();  // 1、创建对象实例,加载Table类,对静态变量进行初始化
    static Cupboard cupboard = new Cupboard();
}

输出:

Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

请问代码的执行顺序是什么?

根据静态初始化和实例初始化的规则,代码的执行顺序如下:

  1. 加载 StaticInitialization 类,对 static Table table = new Table();static Cupboard cupboard = new Cupboard(); 进行初始化
  2. 加载 Table 类,对 static Bowl bowl1 = new Bowl(1);static Bowl bowl2 = new Bowl(2); 进行初始化
  3. 加载 Cupboard 类,对 static Bowl bowl4 = new Bowl(4);static Bowl bowl5 = new Bowl(5); 进行初始化
  4. 执行 main 方法

根据上述执行顺序和每个类中的构造函数和静态变量的初始化顺序,可以解释输出内容如下:

  1. 执行 static Bowl bowl1 = new Bowl(1);,输出 Bowl(1)
  2. 执行 static Bowl bowl2 = new Bowl(2);,输出 Bowl(2)
  3. 执行 static Table table = new Table();,输出 Table()f1(1),因为 Table 的构造函数中有对 bowl2.f1(1) 的调用
  4. 执行 static Bowl bowl4 = new Bowl(4);,输出 Bowl(4)
  5. 执行 static Bowl bowl5 = new Bowl(5);,输出 Bowl(5)
  6. 执行 Bowl bowl3 = new Bowl(3);,输出 Bowl(3)
  7. 执行 Cupboard(),输出 Cupboard()f1(2),因为 Cupboard 的构造函数中有对 bowl4.f1(2) 的调用
  8. 执行 new Cupboard(),输出 Bowl(3)Cupboard()f1(2),因为此时 Cupboard 已经被加载过了,直接创建实例,不会再次加载类
  9. 执行 new Cupboard(),输出 Bowl(3)Cupboard()f1(2),同理
  10. 执行 table.f2(1),输出 f2(1)
  11. 执行 cupboard.f3(1),输出 f3(1)

因此,最终输出的内容应该是:

Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
代码的执行顺序如下:

1、 当程序执行到main方法时,会先加载静态变量table,此时会触发Table类的加载,然后开始初始化静态变量bowl1bowl2,分别输出"Bowl(1)"和"Bowl(2)";接着加载静态变量cupboard,此时会触发Cupboard类的加载,开始初始化静态变量bowl4bowl5,分别输出"Bowl(4)"和"Bowl(5)"。

2、 执行静态变量的初始化后,程序开始执行main方法中的代码,创建一个Cupboard实例,此时会先初始化非静态变量bowl3,输出"Bowl(3)",然后初始化静态变量bowl4,由于bowl4已经被初始化过了,所以不会输出任何内容。接着调用Cupboard类的构造器,输出"Cupboard()"和"f1(2)"。

3、 继续执行main方法中的代码,创建第二个Cupboard实例,此时会先初始化非静态变量bowl3,输出"Bowl(3)",然后初始化静态变量bowl4,由于bowl4已经被初始化过了,所以不会输出任何内容。接着调用Cupboard类的构造器,输出"Cupboard()"和"f1(2)"。

4、 最后执行table.f2(1)cupboard.f3(1),分别输出"f2(1)"和"f3(1)"。

因为静态变量只在类加载时进行初始化,所以静态变量的初始化顺序是按照在类中声明的顺序进行的。而非静态变量则是在每次创建对象时进行初始化。在本例中,由于静态变量和静态代码块只会在类加载时执行一次,所以输出的顺序是先输出静态变量和静态代码块的初始化结果,然后再输出对象的创建和非静态变量的初始化结果。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢