类加载的特殊例题
类的实例化顺序:
-
执行静态代码块
-
执行构造代码块
-
执行构造器
-
普通方法
注意:
-
类中的实例成员,等价于构造代码块。也就是说,构造代码块执行的时候,也会执行实例成员的代码。
-
类中的静态成员,等价于静态块,也就是说,静态块执行的时候,也会执行静态成员的代码。
class Foo { int a = f1(); static int b = f2(); public int f1() { System.out.println("1"); return 5; } public static int f2() { System.out.println("2"); return 10; } public Foo() { System.out.println("3"); } }
2 1 3
先执行静态成员static int b = f2()
,静态成员等价于静态块先执行,如何给b分配空间,然后执行int a = f1()
,类中的实例成员等同于构造代码块,构造代码块执行后执行构造方法。
特殊题:
1 public class Test { 2 public static void main(String[] args) { 3 f1(); 4 } 5 6 static Test t = new Test(); 7 8 static { 9 System.out.println("1"); 10 } 11 12 { 13 System.out.println("2"); 14 } 15 16 Test() { 17 System.out.println("3"); 18 System.out.println("a=" + a + ",b=" + b); 19 } 20 21 public static void f1() { 22 System.out.println("4"); 23 } 24 25 int a = 110; 26 static int b = 112; 27 }
结果:
2
3
a=110,b=0
1
4
静态块之间按顺序执行,所以先执行static Test t = new Test();
,构造代码块优先于构造方法执行(可能有人理解为1应该在2的前面输出),但这里的构造方法是随静态成员的,所以2先输出,然后去执行int a = 110
,这里也可以看成一个构造代码块,先于构造方法执行,所以给a赋值为110,然后输出3,然后输出a,b的值,b此时只在链接过程中分配了空间还没有赋值,所以b为0,构造方法执行完成之后,执行下一个静态代码块,输出1,最后再执行f1()