例如:Test t= new Test();
1).先检查该父类是否已经被加载,如果没有,则执行父类的类加载操作,父类的类加载和子类是一样的,会按照2)和3)的步骤进行加载初始化
2).现在方法区中检查是否已经加载过Test的Class对象信息,如果已经加载过,那么将忽略类加载的流程,直接使用Class对象来构建Test的实例,如果没有加载,这执行步骤二
3).在classpath路径下查找名为Test.class的字节码文件,通过I/O流将其读入内存,接着执行类加载的各个阶段(加载,验证,准备,初始化)。最终由jvm创建该类的一个Class实例保存在堆中。(注意:在准备阶段,会先在方法区中对静态成员的第一次初始化,也就是对静态变量赋默认值。然后在初始化阶段对静态变量进行第二次赋值,也就是字面量声明的值,而第二次赋值是由jvm在动态生成的static代码块中进行赋值操作)
4).通过new关键字创建具体的实例,JVM首先会在堆中划分空间,保存Test的实例对象,实例变量一并跟随的对象保存在堆中,接着初始化实例变量。(注意:实例变量夜神份两阶段进行初始化的,第一阶段就是在划分空间之后立即赋默认值,第二阶段是在构造方法中赋字面声明的值)
5).执行构造方法,在构造方法中对实例变量的再次赋值操作。所以,一个类的构造方法在对象的整个初始化阶段中是最后被执行的。(注意:实例变量的初始化也是先初始化父类的,然后执行父类的构造方法,然后在初始化子类的实例变量,最后执行子类的构造方法)
初始化原则:
加载父类-->初始化父类的静态成员-->加载子类-->初始化子类的静态成员-->
初始化父类的实例变量(默认值)-->构造方法(在构造方法对实例化变量二次赋值)--子类的实例变量初始化(默认值)-->子类的构造方法(在构造方法对子类实例化变量二次赋值)