黑马程序员技术交流社区

标题: 继承和初始化顺序 [打印本页]

作者: yaodd321    时间: 2014-11-3 19:57
标题: 继承和初始化顺序
论坛中已经有很多小伙伴阐述过这个问题,我也用一个例子来说一说
  1. package cn.itcat.damo1;

  2. class Animal {
  3.         Animal(){}
  4.         private static int x1 = f("A"); // 1

  5.         static int f(String s) {
  6.                 System.out.println(s);
  7.                 return 1;
  8.         }
  9. }

  10. class Insect extends Animal {
  11.         private int i = 9;
  12.         protected int j;

  13.         public Insect() {
  14.                 System.out.println("i=" + i + " j=" + j); // 5
  15.                 j = 10;
  16.         }

  17.         private static int x2 = f("B"); // 2

  18. }

  19. public class Bettle extends Insect {
  20.         private int k = f("C"); // 6

  21.         public Bettle() {
  22.                 System.out.println("k=" + k); // 7
  23.                 System.out.println("j=" + j); // 8
  24.         }

  25.         private static int x3 = f("D"); // 3

  26.         public static void main(String[] args) {
  27.                 System.out.println("E"); // 4
  28.                 Bettle b = new Bettle();
  29.         }

  30. }
复制代码

在Bettle上运行java时,所发生的第一件事就是试图访问Bettle.main(),于是加载器开始启动并找出Bettle类的编译代码。在对它进行加载的过程中,编译器注意到它有一个基类(父类)-Insect类,于是它继续加载基类,不管你是否打算产生一个该基类的对象,这都要发生。如果该基类还有其自身的基类-Animal类,则会继续加载。
接下来,根基类中的static初始化被执行,然后是下一个导出类(子类),以此类推,所以1,2,3依次执行。
必要的类都已加载完毕,对象就可以被创建了,4执行。首先,对象中所有的基本类型会被设为默认值,对象引用被设为null,也就是所说的默认初始化。然后基类的构造器会被调用,5执行。在本例中,它是自动调用的,也可以通过super来对指定基类构造器的调用。基类构造器和导出类构造器一样,以相同的顺序经历相同的过程。在基类构造器完成以后,实例变量按照次序初始化,6执行。最后,构造器的其余部分被执行,7,8执行。
所以输出结果:A,B,D,E,i=9 j=0,C,k=1j=10





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2