父类、子类的加载顺序
1、父类的静态变量和静态块赋值(按照声明顺序)
2、自身的静态变量和静态块赋值(按照声明顺序)
3、父类的成员变量和块赋值(按照声明顺序)
4、父类构造器赋值
5、自身成员变量和块赋值(按照声明顺序)
6、自身构造器赋值
7、静态方法,实例方法只有在调用的时候才会去执行
特别注意:当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态(因为非静态可以访问静态,而静态不能访问非静态)
demo说明,结构图如下:
入口Clent类
package com.other; import org.junit.Test; /** *1、牢记:静态和非静态分开处理 * (1)使用到静态加载时,静态又分为: 静态变量, 静态代码块,其中加载顺序是按照类中书写的先后顺序加载的 * (2)非静态加载顺序: 按照非静态书写顺序加载执行 * (3)静态方法,实例方法只有在调用的时候才会去执行 * (4)当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态(因为非静态可以访问静态,而静态不能访问非静态) * * 2、静态变量声明一定放在静态块使用前面 * * 3、入口test方法虽然是一个特殊的静态方法,但是还是静态方法,此时JVM会加载main方法所在的类,试图找到类中其他静态部分 */ public class Client { @Test public void test(){ System.out.println("---new A() Begin---"); A a1 = new A(); System.out.println("---new A() end---\n"); System.out.println("---new B() Begin---"); A a2 = new B(); System.out.println("---new B() end---\n"); System.out.println("---new B() Begin---"); B b = new B(); System.out.println("---new B() end---\n"); System.out.println("---new C() Begin---"); C c = new C(); System.out.println("---new C() end---\n"); System.out.println("---new D() Begin---"); D d = new D(); System.out.println("---new D() end---\n"); System.out.println("---new E() Begin---"); E e = new E(); System.out.println("---new E() end---\n"); } }
打印结果如下:
---new A() Begin---
init B static variable B1
init B static block
init C static variable C1
init C static block
init A variable A2
init A block
init A constructor
init B variable B2
init B block
init B constructor
init C variable C2
init C block
init C constructor
init A static variable A1
init A static block
init A variable A2
init A block
init A constructor
---new A() end------new B() Begin---
init A variable A2
init A block
init A constructor
init B variable B2
init B block
init B constructor
---new B() end------new B() Begin---
init A variable A2
init A block
init A constructor
init B variable B2
init B block
init B constructor
---new B() end------new C() Begin---
init A variable A2
init A block
init A constructor
init B variable B2
init B block
init B constructor
init C variable C2
init C block
init C constructor
---new C() end------new D() Begin---
init D static variable D1
init D static block
init A variable A2
init A block
init A constructor
init B variable B2
init B block
init B constructor
init D variable D2
init D block
init D constructor
---new D() end------new E() Begin---
init E static variable E1
init E static block
init A variable A2
init A block
init A constructor
init E variable E2
init E block
init E constructor
---new E() end---
父类A
package com.other; public class A { public static String A1 = "A1"; public static C CC = new C();//当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态(因为非静态可以访问静态,而静态不能访问非静态) public String A2 = "A2"; public A(){//构造函数,默认先调用父类的无参构造函数 System.out.println("init A constructor "); } static {//静态代码块,静态代码块是主动运行的,而静态方法是被动运行 System.out.println("init A static variable " + A1); System.out.println("init A static block "); } {//构造代码块,构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优先于构造函数执行 System.out.println("init A variable " + A2); System.out.println("init A block "); } public void show(){//普通方法,通过对象才能运行这个方法 { //普通代码块,普通代码块和构造代码块的区别是, // 构造代码块是在类中定义的,普通代码块是在方法体中定义的 System.out.println("普通代码块"); } } public static void show2(){//静态方法,通过类名或者对象名才能访问 { System.out.println("普通代码块"); } } }
子类B
package com.other; public class B extends A { public static String B1 = "B1"; public String B2 = "B2"; public B(){ System.out.println("init B constructor "); } static { System.out.println("init B static variable " + B1); System.out.println("init B static block "); } { System.out.println("init B variable " + B2); System.out.println("init B block "); } }
子子类C
package com.other; public class C extends B { public static String C1 = "C1"; public String C2 = "C2"; public C(){ System.out.println("init C constructor "); } static { System.out.println("init C static variable " + C1); System.out.println("init C static block "); } { System.out.println("init C variable " + C2); System.out.println("init C block "); } }
子子类D
package com.other; public class D extends B { public static String D1 = "D1"; public String D2 = "D2"; public D(){ System.out.println("init D constructor "); } static { System.out.println("init D static variable " + D1); System.out.println("init D static block "); } { System.out.println("init D variable " + D2); System.out.println("init D block "); } }
子类E
package com.other; public class E extends A { public static String E1 = "E1"; public String E2 = "E2"; public E(){ System.out.println("init E constructor "); } static { System.out.println("init E static variable " + E1); System.out.println("init E static block "); } { System.out.println("init E variable " + E2); System.out.println("init E block "); } }