父类、子类的加载顺序
1、父类的静态变量和静态块赋值(按照声明顺序)
2、自身的静态变量和静态块赋值(按照声明顺序)
3、父类的成员变量和块赋值(按照声明顺序)
4、父类构造器赋值
5、自身成员变量和块赋值(按照声明顺序)
6、自身构造器赋值
7、静态方法,实例方法只有在调用的时候才会去执行
特别注意:当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态(因为非静态可以访问静态,而静态不能访问非静态)
demo说明,结构图如下:
入口Client类
package com.other;
import org.junit.Test;
/**
*1、牢记:静态和非静态分开处理
* (1)使用到静态加载时,静态又分为: 静态变量, 静态代码块,其中加载顺序是按照类中书写的先后顺序加载的
* (2)非静态加载顺序: 按照非静态书写顺序加载执行
* (3)静态方法,实例方法只有在调用的时候才会去执行
* (4)当静态加载中遇到需要加载非静态的情况: 先加载非静态再加载静态(因为非静态可以访问静态,而静态不能访问非静态)
*
* 2、静态变量声明一定放在静态块使用前面
*
* 3、入口test方法虽然是一个特殊的静态方法,但是还是静态方法,此时JVM会加载test方法所在的类,试图找到类中其他静态部分
*/
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 ");
}
}