例:
class Insect{
int i=9;
int j;
Insect(){
prt("i="+i+",j="+j);
j=39;
}
static int x1=prt("static Insect.x1");
static int prt(String s){
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect{
int k=prt("beetle.k");
Beetle(){
prt("k="+k);
prt("j="+j);
}
static int x2=prt("static Beetle.x2");
public static void main(String[] args){
prt("Beetle constructor");
Beetle b=new Beetle();
}
}
输出结果:
static Insect.x1
static Beetle.x2
Beetle constructor
i=9,j=0
beetle.k
k=47
j=39
首先要明确三条规则:
一JVM用到某个类时才会将该类装载进来,如果该类拥有父类,则会先将该类的父类装载进来。
二当一个类被JVM装载,则会初始化static修饰的成员。
三当调用某个类的构造函数时,如果该类拥有父类,则会先调用父类的构造函数。在执行构造函数里的语
句前,先会初始化该类中非static的成员(static修饰的成员在装载时已被初始化).
了解了以上三点后,对以上输出结果进行分析:
首先程序的入口是main(),在Beetle这个类中,又由于该类有父类Insect,根据第一,二条规则,首先装载Insect类,初始化Insect内的静态成员,输出static Insect.x1。接着装载Beetle类,初始化Beetle的静态成员,输出static Beetle.x2
这个时候才开始执行main()中的语句:
prt("Beetle constructor");输出Beetle constructor。
Beetle b=new Beetle();会调用Beetle的无参构造方法,根据第三条规则,会调用其父类Insect的无参构造方法(),在执行该方法之前,会初始化变量i=9;j=0;接着执行该方法内的语句:
prt("i="+i+",j="+j);输出i=9,j=0 。这时候j=39.
初始化Beetle内的成员,
int k=prt("beetle.k");输出:beetle.k。k=47。
最后才执行Beetle构造方法内的语句:
prt("k="+k);输出k=47
prt("j="+j);输出j=39