首页 > 代码库 > Java 的类加载顺序

Java 的类加载顺序

 

Java 的类加载顺序

一、加载顺序

1、父类的静态成员变量初始化

  1.1、静态代码块

  1.2、普通代码块

  1.3、无参构造器

2、父类的静态代码块

3、子类的静态成员变量初始化

  3.1、静态代码块

  3.2、普通代码块

  3.3、无参构造器

4、子类的静态代码块

5、父类的普通成员变量初始化

  5.1、静态代码块

  5.2、普通代码块

  5.3、无参构造器

6、父类的普通代码块

7、父类的无参构造器

8、子类的普通成员变量

  8.1、静态代码块

  8.2、普通代码块

  8.3、无参构造器

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

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title A
* @describe 超级父类 A
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class A {

  //普通成员变量

 

  private AA aa = new AA();

  //静态成员变量
  private static AAA aaa = new AAA();

 

  // 静态代码块
  static {
    System.out.println("我是超级父类 A 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是超级父类 A 的普通代码块");
  }

 

  // 无参构造方法
  public A() {
    System.out.println("我是超级父类 A 的无参构造方法");
  }
}

 

2、父类B

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title B
* @describe 父类
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class B extends A {

  //普通成员变量
  private BB bb = new BB();

  //静态成员变量
  private static BBB bbb = new BBB();

 

  // 静态代码块
  static {
    System.out.println("我是父类 B 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是父类 B 的普通代码块");
  }

 

  // 无参构造方法
  public B() {
    System.out.println("我是父类 B 的无参构造方法");
  }
}

 

3、子类C

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title C
* @describe 子类 C
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class C extends B {

  //普通成员变量

  private CC cc = new CC();

  //静态成员变量
  private static CCC ccc = new CCC();


  // 静态代码块
  static {
    System.out.println("我是子类 C 的静态代码块");
  }

 

  // 普通代码块
  {
  System.out.println("我是子类 C 的普通代码块");
  }

 

  // 无参构造方法
  public C() {
    System.out.println("我是子类 C 的无参构造方法");
  }
}

 

4、AA类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title AA
* @describe 超级父类 A 的普通成员变量 AA
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class AA {
  // 静态代码块
  static {
    System.out.println("我是超级父类 A 的普通成员变量 AA 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是超级父类 A 的普通成员变量 AA 的普通代码块");
  }

 

  // 无参构造方法
  public AA() {
    System.out.println("我是超级父类 A 的普通成员变量 AA 的无参构造方法");
  }
}

 

5、AAA类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title AAA
* @describe 超级父类 A 的静态成员变量 AAA
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class AAA {
  // 静态代码块
  static {
    System.out.println("我是超级父类 A 的静态成员变量 AAA 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是超级父类 A 的静态成员变量 AAA 的普通代码块");
  }

 

  // 无参构造方法
  public AAA() {
    System.out.println("我是超级父类 A 的静态成员变量 AAA 的无参构造方法");
  }
}

 

6、BB类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title BB
* @describe 父类 B 的普通成员变量 BB
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class BB {
  // 静态代码块
  static {
    System.out.println("我是父类 B 的普通成员变量 BB 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是父类 B 的普通成员变量 BB 的普通代码块");
  }

 

  // 无参构造方法
  public BB() {
    System.out.println("我是父类 B 的普通成员变量 BB 的无参构造方法");
  }
}

 

7、BBB类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title BBB
* @describe 父类 B 的静态成员变量 BBB
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class BBB {
  // 静态代码块
  static {
    System.out.println("我是父类 B 的静态成员变量 BBB 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是父类 B 的静态成员变量 BBB 的普通代码块");
  }

 

  // 无参构造方法
  public BBB() {
    System.out.println("我是父类 B 的静态成员变量 BBB 的无参构造方法");
  }
}

 

8、CC类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title CC
* @describe 子类 C 的普通成员变量 CC
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class CC {
  // 静态代码块
  static {
    System.out.println("我是子类 C 的普通成员变量 CC 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是子类 C 的普通成员变量 CC 的普通代码块");
  }

 

  // 无参构造方法
  public CC() {
    System.out.println("我是子类 C 的普通成员变量 CC 的无参构造方法");
  }
}

 

9、CCC类

 

package cn.com.zfc.lesson05.inherit01;

 

/**
*
* @title CCC
* @describe 子类 C 的静态成员变量 CCC
* @author 张富昌
* @date 2017年4月3日下午5:59:17
*/
public class CCC {
  // 静态代码块
  static {
    System.out.println("我是子类 C 的静态成员变量 CCC 的静态代码块");
  }

 

  // 普通代码块
  {
    System.out.println("我是子类 C 的静态成员变量 CCC 的普通代码块");
  }

 

  // 无参构造方法
  public CCC() {
    System.out.println("我是子类 C 的静态成员变量 CCC 的无参构造方法");
  }
}

10、测试子类C的创建过程:TestC.java

package cn.com.zfc.lesson05.inherit01;
/**
*
* @title TestC
* @describe 测试子类C的创建过程
* @author 张富昌
* @date 2017年4月3日下午6:49:50
*/
public class TestC {
  public static void main(String[] args) {

    //创建 C 对象
    C c = new C();
  }
}

三、测试结果

 

我是超级父类 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 的无参构造方法

 

 

总结:

  第一点,所有的类都会优先加载基类
  第二点,静态成员的初始化优先
  第三点,成员初始化后,才会执行构造方法
  第四点,静态成员的初始化与静态块的执行,发生在类加载的时候。
  第四点,类对象的创建以及静态块的访问,都会触发类的加载。

Java 的类加载顺序