这个阶段才真正开始执行java代码,静态代码块和设置变量的初始值为程序员设定的值
主动引用
有且只有下面5种情况才会立即初始化类,称为主动引用:
第一种:遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类还没有进行过初始化,则需要先触发其初始化。生成这四条指令最常见的Java代码场景是:使用new关键字实例化对象时、读取或设置一个类的静态字段(static)时(被static修饰又被final修饰的,已在编译期把结果放入常量池的静态字段除外)、以及调用一个类的静态方法时。
第二种:使用Java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化,则需要先触发其初始化。
第三种:当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
第四种:当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先执行该主类。
第五种:当使用JDK1.5支持时,如果一个java.langl.incoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
其他对类的引用 称为被动引用,加载类时不会进行初始化动作,如:
通过子类引用父类的静态字段,子类不会被初始化。
通过数组定义来引用类。
通过类的常量。
子类继承父类时的初始化顺序
1.首先初始化父类的static变量和块,按出现顺序
2.初始化子类的static变量和块,按出现顺序
3.初始化父类的普通变量,调用父类的构造函数
4.初始化子类的普通变量,调用子类的构造函数