Java 的类加载顺序
一、加载顺序:先父类后子类,先静态后普通
1、父类的静态成员变量初始化
2、父类的静态代码块
3、子类的静态成员变量初始化
4、子类的静态代码块
5、父类的普通成员变量初始化
6、父类的普通代码块
7、父类的无参构造器
8、子类的普通成员变量
9、子类的普通代码块
10、子类的无参构造器
二、示例代码
超级父类A,父类B,子类C,B继承A,C继承B;
AA、AAA、BB、BBB、CC、CCC都有各自的普通、静态成员变量,普通、静态代码块和无参构造器
超级父类A的普通成员变量aa(AA类的实例),超级父类A的静态成员变量aaa(AAA类的实例);
父类B的普通成员变量bb(BB类的实例),父类B的静态成员变量bbb(BBB类的实例);
子类C的普通成员变量cc(CC类的实例),子类C的静态成员变量ccc(CCC类的实例);
1、超级父类A
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title A 6 * @describe 超级父类 A 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class A { 11 12 //普通成员变量 13 14 private AA aa = new AA(); 15 16 //静态成员变量 17 private static AAA aaa = new AAA(); 18 19 20 21 // 静态代码块 22 static { 23 System.out.println("我是超级父类 A 的静态代码块"); 24 } 25 26 27 28 // 普通代码块 29 { 30 System.out.println("我是超级父类 A 的普通代码块"); 31 } 32 33 34 35 // 无参构造方法 36 public A() { 37 System.out.println("我是超级父类 A 的无参构造方法"); 38 } 39 }
2、父类B
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title B 6 * @describe 父类 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class B extends A { 11 12 //普通成员变量 13 private BB bb = new BB(); 14 15 //静态成员变量 16 private static BBB bbb = new BBB(); 17 18 19 20 // 静态代码块 21 static { 22 System.out.println("我是父类 B 的静态代码块"); 23 } 24 25 26 27 // 普通代码块 28 { 29 System.out.println("我是父类 B 的普通代码块"); 30 } 31 32 33 34 // 无参构造方法 35 public B() { 36 System.out.println("我是父类 B 的无参构造方法"); 37 } 38 }
3、子类C
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title C 6 * @describe 子类 C 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class C extends B { 11 12 //普通成员变量 13 14 private CC cc = new CC(); 15 16 //静态成员变量 17 private static CCC ccc = new CCC(); 18 19 20 // 静态代码块 21 static { 22 System.out.println("我是子类 C 的静态代码块"); 23 } 24 25 26 27 // 普通代码块 28 { 29 System.out.println("我是子类 C 的普通代码块"); 30 } 31 32 33 34 // 无参构造方法 35 public C() { 36 System.out.println("我是子类 C 的无参构造方法"); 37 } 38 }
4、AA类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title AA 6 * @describe 超级父类 A 的普通成员变量 AA 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class AA { 11 // 静态代码块 12 static { 13 System.out.println("我是超级父类 A 的普通成员变量 AA 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是超级父类 A 的普通成员变量 AA 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public AA() { 27 System.out.println("我是超级父类 A 的普通成员变量 AA 的无参构造方法"); 28 } 29 }
5、AAA类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title AAA 6 * @describe 超级父类 A 的静态成员变量 AAA 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class AAA { 11 // 静态代码块 12 static { 13 System.out.println("我是超级父类 A 的静态成员变量 AAA 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是超级父类 A 的静态成员变量 AAA 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public AAA() { 27 System.out.println("我是超级父类 A 的静态成员变量 AAA 的无参构造方法"); 28 } 29 }
6、BB类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title BB 6 * @describe 父类 B 的普通成员变量 BB 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class BB { 11 // 静态代码块 12 static { 13 System.out.println("我是父类 B 的普通成员变量 BB 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是父类 B 的普通成员变量 BB 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public BB() { 27 System.out.println("我是父类 B 的普通成员变量 BB 的无参构造方法"); 28 } 29 }
7、BBB类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title BBB 6 * @describe 父类 B 的静态成员变量 BBB 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class BBB { 11 // 静态代码块 12 static { 13 System.out.println("我是父类 B 的静态成员变量 BBB 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是父类 B 的静态成员变量 BBB 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public BBB() { 27 System.out.println("我是父类 B 的静态成员变量 BBB 的无参构造方法"); 28 } 29 }
8、CC类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title CC 6 * @describe 子类 C 的普通成员变量 CC 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class CC { 11 // 静态代码块 12 static { 13 System.out.println("我是子类 C 的普通成员变量 CC 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是子类 C 的普通成员变量 CC 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public CC() { 27 System.out.println("我是子类 C 的普通成员变量 CC 的无参构造方法"); 28 } 29 }
9、CCC类
1 package cn.com.zfc.lesson05.inherit01; 2 3 /** 4 * 5 * @title CCC 6 * @describe 子类 C 的静态成员变量 CCC 7 * @author 张富昌 8 * @date 2017年4月3日下午5:59:17 9 */ 10 public class CCC { 11 // 静态代码块 12 static { 13 System.out.println("我是子类 C 的静态成员变量 CCC 的静态代码块"); 14 } 15 16 17 18 // 普通代码块 19 { 20 System.out.println("我是子类 C 的静态成员变量 CCC 的普通代码块"); 21 } 22 23 24 25 // 无参构造方法 26 public CCC() { 27 System.out.println("我是子类 C 的静态成员变量 CCC 的无参构造方法"); 28 } 29 }
10、测试子类C的创建过程:TestC.java
1 package cn.com.zfc.lesson05.inherit01; 2 /** 3 * 4 * @title TestC 5 * @describe 测试子类C的创建过程 6 * @author 张富昌 7 * @date 2017年4月3日下午6:49:50 8 */ 9 public class TestC { 10 public static void main(String[] args) { 11 12 //创建 C 对象 13 C c = new C(); 14 } 15 }
三、测试结果
我是超级父类 A 的静态成员变量 AAA 的静态代码块
我是超级父类 A 的静态成员变量 AAA 的普通代码块
我是超级父类 A 的静态成员变量 AAA 的无参构造方法
我是超级父类 A 的静态代码块
我是父类 B 的静态成员变量 BBB 的静态代码块
我是父类 B 的静态成员变量 BBB 的普通代码块
我是父类 B 的静态成员变量 BBB 的无参构造方法
我是父类 B 的静态代码块
我是子类 C 的静态成员变量 CCC 的静态代码块
我是子类 C 的静态成员变量 CCC 的普通代码块
我是子类 C 的静态成员变量 CCC 的无参构造方法
我是子类 C 的静态代码块
我是超级父类 A 的普通成员变量 AA 的静态代码块
我是超级父类 A 的普通成员变量 AA 的普通代码块
我是超级父类 A 的普通成员变量 AA 的无参构造方法
我是超级父类 A 的普通代码块
我是超级父类 A 的无参构造方法
我是父类 B 的普通成员变量 BB 的静态代码块
我是父类 B 的普通成员变量 BB 的普通代码块
我是父类 B 的普通成员变量 BB 的无参构造方法
我是父类 B 的普通代码块
我是父类 B 的无参构造方法
我是子类 C 的普通成员变量 CC 的静态代码块
我是子类 C 的普通成员变量 CC 的普通代码块
我是子类 C 的普通成员变量 CC 的无参构造方法
我是子类 C 的普通代码块
我是子类 C 的无参构造方法
总结:
第一点,所有的类都会优先加载基类
第二点,静态成员的初始化优先
第三点,成员初始化后,才会执行构造方法
第四点,静态成员的初始化与静态块的执行,发生在类加载的时候。
第四点,类对象的创建以及静态块的访问,都会触发类的加载。