当一个JAVA运行时,了解包括继承在内的初始化全过程,以对所发生的一切有个全局性的把握,是很有益的。
代码演示
package code01;
class Father {
private int i = 9;
protected int j;
Father() {
System.out.println("i = " + i + ",j = " + j + ", x1 = " + x1);
j = 39;
}
static {
System.out.println("Father静态代码块初始化");
}
{
System.out.println("Father代码块初始化");
}
private static int x1 = printInit("static Father.x1 initialized");
protected static int printInit(String s) {
System.out.println(s);
return 7;
}
}
public class son extends Father {
static {
System.out.println("son静态代码块初始化");
}
private static int x2 = printInit("static son.x2 initialed");
private int k = printInit("son.k initialed");
{
System.out.println("son代码块初始化");
}
public son() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}
public static void main(String[] args) {
System.out.println("son constructor");
son one = new son();
}
}
测试结果
Father静态代码块初始化
static Father.x1 initialized
son静态代码块初始化
static son.x2 initialed
son constructor
Father代码块初始化
i = 9,j = 0, x1 = 7
son.k initialed
son代码块初始化
k = 7
j = 39
总体分析
在运行Java时,所发生的第一件事就访问main()方法(static方法) 于是加载器开始启动并找出son 的编译代码。在对它进行加载的过程中,编译器注意到他有一个基类,于是他继续进行加载,不管你是否打算产生一个该基类的对象(强制加载)
如果该基类还有自身的基类,那么第二个基类就会被加载,接下来,根基类的static初始化(按照顺序来初始化: 静态变量和静态块),然后是下一个导出类。
到此为止,必要的类都已经加载完毕,对象就可以被创建了,首先,对象中所有的基本类型都会被设置为默认值(已在变量声明时赋值的不算),对象引用被设为null 。首先基类的代码块首先初始化。然后基类的构造器会被调用,它可以被自动调用,也可以使用super来指定基类构造器的调用。实例变量按其次序被初始化,最后构造器的其余部分被执行。然后是子类继续按照上面初始化