疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java类加载中的顺序


 

   

  之前说过Java中类的加载顺序,这次看完继承部分,就结合继承再来说说类的加载顺序。

  继承的加载顺序

  由于static块会在首次加载类的时候执行,因此下面的例子就是用static块来测试类的加载顺序。

  package xing.test.thinking.chap7;

  class A{

  static{

  System.out.println("A static");

  }

  }

  class B extends A{

  static{

  System.out.println("B static");

  }

  }

  class C extends B{

  private static D d = new D();

  static{

  System.out.println("C static");

  }

  }

  class D{

  static{

  System.out.println("D static");

  }

  }

  public class ExtendTest {

  public static void main(String[] args) {

  C c = new C();

  }

  }

  在上面的例子中,类C继承B,B继承A,而C有依赖于D。因此当创建C的时候,会自动加载C继承的B和依赖的D,然后B又会加载继承的A。只有A加载完,才能顺利的加载B;BD加载完,才能加载C。这就是类的加载顺序了。

  A static

  B static

  D static

  C static

  所有的变量初始化完,才会执行构造方法

  在类的加载过程中,只有内部的变量创建完,才会去执行这个类的构造方法。

  package xing.test.thinking.chap7;

  class A2{

  B2 b2 = new B2();

  static{

  System.out.println("A static");

  }

  public A2() {

  System.out.println("A2()");

  }

  }

  class B2{

  C2 c2 = new C2();

  D2 d2 = new D2();

  static{

  System.out.println("B static");

  }

  public B2() {

  System.out.println("B2()");

  }

  }

  class C2{

  static{

  System.out.println("C static");

  }

  public C2() {

  System.out.println("C2()");

  }

  }

  class D2{

  static{

  System.out.println("D static");

  }

  public D2() {

  System.out.println("D2()");

  }

  }

  public class VarTest {

  public static void main(String[] args) {

  A2 a2 = new A2();

  }

  }

  在上面的例子中,A2里面有B2变量,B2则有C2D2变量。因此类的加载还是先读取到哪个,就执行相应的静态块。

  当依赖的对象都定义完,才会执行构造方法:

  A static

  B static

  C static

  C2()

  D static

  D2()

  B2()

  A2()

  静态成员与普通成员类的加载区别

  在类的加载过程中,静态成员类的对象,会优先加载;而普通成员类的对象则是使用的时候才回去加载。

  package xing.test.thinking.chap7;

  class A3{

  B3 b3 = new B3();

  static C3 c4 = new C3();

  static{

  System.out.println("A3");

  }

  }

  class B3{

  static{

  System.out.println("B3");

  }

  }

  class C3{

  static{

  System.out.println("C3");

  }

  }

  public class StaticTest {

  public static void main(String[] args) {

  A3 a3 = new A3();

  }

  }

  输出:

  C3

  A3

  B3

  总结

  第一点,所有的类都会优先加载基类

  第二点,静态成员的初始化优先

  第三点,成员初始化后,才会执行构造方法

  第四点,静态成员的初始化与静态块的执行,发生在类加载的时候。

  第四点,类对象的创建以及静态块的访问,都会触发类的加载。