1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class Main {
public static void main(String[] args) { new Main(); }
static int num = 4;
{ num += 3; System.out.println("b"); }
int a = 5;
{ System.out.println("c"); }
Main() { System.out.println("d"); }
static { System.out.println("a"); }
static void run() { System.out.println("e"); } }
|
执行以上代码可以总结加载顺序:静态代码块(静态变量) -> 匿名代码块(成员变量) -> 构造方法 -> 静态方法(不调用不加载
- 静态代码块只加载一次
- 静态方法只有调用才会加载
- 静态代码块和静态变量按照代码编写前后顺序执行
- 匿名代码块和成员变量按照代码编写前后顺序执行
1 2 3 4 5
| public class Print { public Print(String s) { System.out.println(s + " "); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Parent { public static Print obj1 = new Print("1");
public Print obj2 = new Print("2");
public static Print obj3 = new Print("3");
static { new Print("4"); }
public static Print obj4 = new Print("5");
public Print obj5 = new Print("6");
public Parent() { new Print("7"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Child extends Parent { static { new Print("a"); }
public static Print obj1 = new Print("b");
public Print obj2 = new Print("c");
public Child() { new Print("d"); }
public static Print obj3 = new Print("e");
public Print obj4 = new Print("f");
public static void main(String[] args) { Parent obj1 = new Child();
Parent obj2 = new Child(); } }
|
执行main方法打印顺序:1 3 4 5 a b e 2 6 7 c f d 2 6 7 c f d
- 先执行父类的静态代码块和静态变量初始化,并且静态代码块和静态变量的执行顺序只跟代码中出现的顺序有关;
- 执行子类的静态代码块和静态变量初始化;
- 执行父类的实例变量初始化;
- 执行父类的构造函数;
- 执行子类的实例变量初始化;
- 执行子类的构造函数;
如果类已经被加载,则静态代码块和静态变量就不用重复执行,再创建类对象时,只执行与实例相关变量初始化和构造方法