public 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");
protected static int printInit(String string) {
// TODO Auto-generated method stub
System.out.println(string);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initalized");
public Beetle() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}
private static int x2 =
printInit("static Beele.x2 initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle();
}
}
上面的输出结果为
static Insect.x1 initialized
static Beele.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initalized
k = 47
j = 39
而将Beetle b = new Beetle()这句注掉输出结果为
static Insect.x1 initialized
static Beele.x2 initialized
Beetle constructor
对比以上结果则类的加载和初始化规律为
1.加载类的时候并不会初始化非静态代码,实例化的时候才会初始化非静态代码。
2.类是在任何static成员被访问时加载的。
一般情况加载发生在创建类的第一个实例,由于构造器也是static方法,也是符合这个规律的。
加载时会先初始化父类static变量,再初始化子类static变量,static变量只会被初始化一次。
如本例,Beetle在运行时,试图访问Beetle.main,于是开始找出Beetle类进行加载。
3.在new 一个类的实例的时候会按照如下顺序初始化:
父类非静态变量/代码块->父类构造函数->子类非静态变量/代码块->子类构造函数。