以下面的代码作为例子:
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 40;
}
}
public class Beetle extends Insect{
private int k=printInit(" Beetle.k initialized");
public Beetle() {
System.out.println("k="+k);
System.out.println("j="+j);
}
private static int x2=printInit("static Beetle.x2 initialized");
private static int x3=printInit("x3");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle beetle=new Beetle();
}
}
输出结果为:
static Insect.x1 initialized
static Beetle.x2 initialized
x3
Beetle constructor
i=9j=0
Beetle.k initialized
k=40
j=39
《Java编程思想》:在Beetle上运行Java时,发生的第一件事就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件之中)。在对他进行加载的过程中,编译器注意到他有一个基类(这是由关键字extends得知的),于是它继续加载(该基类),不管你是否打算产生一个该基类的对象,这都会发生。如果该基类还有其自身的基类,那么第二个基类会被加载,如此类推,直到根基类。接下来,根基类(在本例中时Insect)中的static初始化将被执行,然后是下一个导出类,以此类推。
至此为止,必要的类都已加载完毕,对象就可以被创建了(在本例中,Beetle beetle=new Beetle())。首先,对象中所有的基本类型都会被设为默认值,对象中的对象引用被设为null。然后,基类的构造器被调用。在基类构造器被调用完成之后,实例变量按顺序被初始化,最后,构造器的其余部分被执行。
在本例中,根基类是Insect,所以首先会初始化Insect中的static,也就是x1。然后他的导出类Beetle同样初始化static,x2、x3被初始化。初始化结束后会按顺序执行main()中的内容。先是打印“Beetle constructor”,然后创建Beetle对象。创建Beetle对象会先调用他的父类的构造方法。调用父类的构造方法时会打印“i=9j=0”。然后Beetle的成员变量被初始化,打印“ Beetle.k initialized”。最后调用到Beetle的构造方法,打印“k=40
j=39”
总结:首先找到main类的根基类,然后按继承顺序从父类到子类,先对static初始化。然后按顺序执行main()方法中的代码。