不管有没有创建对象:
加载器启动并找出运行类的编译代码(对其进行加载),若其含有基类则继续加载基类(加载的顺序是由导出类向基类依次加载)。
static成员初始化(由根基类向导出类的顺序初始化,而在类中按定义类时的书写顺序,方法只有被调用时才会被执行)。
运行类中的main方法被调用。
若创建对象:
非static成员初始化—>构造器(由根基类向导出类的顺序初始化,而在类中非static成员初始化按定义类时的书写顺序)。
PS. 当一个类的非static成员初始化完成和构造函数运行后才会进行子类的初始化。
当非static成员是引用时,即在初始化的过程中用new创建了一个对象,该对象的初始化也会按Java初始化顺序进行初始化。
总结:
1.若没有创建对象:基类static成员—>导出类static成员—>main方法
2.若数据成员为new关键字创建的对象:该对象基类static成员—>该对象类型的static成员—>该对象基类非static成员—>该对象基类构造器—>该对象类型的非static成员—>该对象类型的构造器
3.若在main中创建了对象:基类的static成员—>导出类的static成员—>main方法—>情况2
下面是Demo代码,有助于实际的理解,以上内容纯属于自己看书后的理解,当然可能有些语言组织不当,或者还存在一些问题,希望各位大牛指出。
class ExtraT{
private int i = printInt("ExtraT.i");
protected int j;
ExtraT(){
System.out.println("ExtraT.i=" + i + ",ExtraT.j=" + j);
j = 1;
}
private static int x1 = printInt("static ExtraT.x1");
static int printInt(String s){
System.out.println(s);
return 1024;
}
}
class BaseT{
private int m = printInt("BaseT.m");
protected int n;
private static int x2 = printInt("static BaseT.x2");
BaseT(){
System.out.println("BaseT.m=" + m + ",BaseT.n=" + n);
n = 2;
}
private static int x1 = printInt("static BaseT.x1");
static int printInt(String s){
System.out.println(s);
return 2048;
}
}
public class Test extends BaseT{
private int a = printInt("Test.k");
private static int x1 = printInt("static Test.x1");
private static ExtraT eT = new ExtraT();
public Test(){
System.out.println("Test.a=" + a + ",Test.n=" + n);
}
public static void main(String[] args) {
System.out.println("Test Contructor");
Test t = new Test();
}
private static int x2 = printInt("static Test.x2");
}
/**
* Output
*
static BaseT.x2
static BaseT.x1
static Test.x1
static ExtraT.x1
ExtraT.i
ExtraT.i=1024,ExtraT.j=0
static Test.x2
Test Contructor
BaseT.m
BaseT.m=2048,BaseT.n=0
Test.k
Test.a=2048,Test.n=2
*/