了解包括继承在内的初始化全过程,以对所发生的的一切有一个全局的把握,是颇有益的。java
请看下例:spa
package initialize; class Insect { private int i = 9; protected int j; Insect() { System.out.println("i = " + i + ", j = " + j); j = 39; } private static int x1 = printInit("static Insect.x1 initialized"); static int printInit(String s) { System.out.println(s); return 47; } } public class Beetle extends Insect{ private int k = printInit("Beelte.k initialized"); public Beetle(){ System.out.println("k = " + k); System.out.println("j = " + j); } private static int x2 = printInit("static Beetle.x2 initialized"); public static void main(String[] args) { System.out.println("Beetle constructor"); //Beetle beetle = new Beetle(); //此处先注释 } }
运行结果:对象
在运行Beetle时,所发生的第一件事就是试图访问Beetel.main()方法(程序入口)(一个static方法),blog
因而加载器就开始启动并找到Beetel类的编译代码(在Beetle.class文件中)。对他进行加载时,发现他有一个基类(这是由“extents”关键字得知的),因而继续进行加载该基类。无论是否你是否打算生成一个该基类的对象,都会发生。从上出代码Beelte.main()方法中的注释代码证实这一点。继承
若是该基类还有其自身的基类,那么第二个就会被加载,如此类推。接下来,根基类中的static方法初始化(此例中为Insect)即会被执行,而后是下一个导出类,如此类推。it
至此,必要的类都加载完毕,对象就能够建立了,咱们把上面的Beelte.main()方法中的注释代码取消,编译
运行结果:class
首先对象中全部基本类型都会被设为某默认值,对象引用都设为null,而后基类的构造器会被调用。基类的构造器和导出类的构造器同样,以相同的顺序经历相同的过程。基类构造器完成以后,实例变量按其次序被初始化。变量
习题:请证实加载类的动做只发生一次。证实该类的第一个实体的建立或static成员的访问都有可能引发加载。引用
在Beelte.main()方法中添加一行代码:
Beetle beetle2 = new Beetle();
输出结果: