虚拟机将Class文件加载进内存,校验数据、转换解析、初始化,最终形成可以被虚拟机直接使用的Java类型。一个类的生命周期如下图::
除解析外,其他过程都是确定顺序的。
类加载的时机:触发一个类进行加载分为主动加载和被动加载,主动加载比如有new关键字、使用静态字段、调用静态方法等。
类加载的过程
jvm类加载器,类加载机制详解,看这一篇就够了 - SegmentFault 思否
加载:加载二进制数据到内存 —> 映射成jvm能识别的结构 —> 在内存中生成class文件。
验证:确保class文件中的字节流包含的信息,符合当前虚拟机的要求,保证这个被加载的class类的正确性,不会危害到虚拟机的安全。
准备:为类中的静态字段分配内存,并设置默认的初始值,比如int类型初始值是0。
解析:
解析阶段的目的,是将常量池内的符号引用转换为直接引用的过程(将常量池内的符号引用解析成为实际引用)。如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。)
事实上,解析器操作往往会伴随着 JVM 在执行完初始化之后再执行。 符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《Java 虚拟机规范》的Class文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
解析动作主要针对类、接口、字段、类方法、接口方法、方法类型等。对应常量池中的 CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等。
初始化:
初始化就是执行类的构造器方法init()的过程。
这个方法不需要定义,是javac编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并来的。
若该类具有父类,jvm会保证父类的init先执行,然后在执行子类的init。