类从被加载到虚拟机内存开始,直到卸载出内存为止,它的整个生命周期包括:
加载、验证、准备、解析、初始化、使用、卸载等7个过程,其中验证、准备、解析部分称为连接
其中 加载、验证、准备、初始化、卸载相对顺序是确定的,而解析阶段不一定,它可以在初始化阶段之后进行,这些阶段是交互进行的,通常会在一个阶段执行过程中调用**下一阶段
类加载的时机并没有具体的确定规则,而虚拟机规定了有且只有5种情况必须立即对类进行初始化(注意区分对象初始化)
(而加载,验证,准备自然需要在此之前进行)
——遇到new getstatic putstatic invokestatic这4条字节码指令时,如果类没有进行初始化,则必须先触发初始化过程。常见的Java代码场景:使用new关键字实例化对象、读取或设置一个类的静态字段(final字段除外)、调用类的静态方法时
——使用java.lang.reflect包的方法对类进行反射调用时候,如果类没有进行过初始化,则先触发初始化
——当初始化一个类时候,如果发现其父类还没有初始化,则先触发父类初始化
——当虚拟机启动时候,用户需要指定一个要执行的主类(main()对应的类) 虚拟机会先初始化这个主类
——当使用JDK1.7之后的动态语言支持时,如果一个java.lang.invoke实例解析结果REF_getStatic,REF_putStatic方法句柄,并且该方法对应的类没有初始化
这5种场景下会对一个类主动进行引用,称为”主动引用“ 而其它引用类的方式不会触发初始化,称为”被动引用“