加载机制:虚拟机把class文件加载到内存,并进行数据校验、转化解析和初始化,最终形成可以被虚拟机直接使用的java类型。
类的生命周期:加载、验证、准备、解析、初始化、使用、卸载。
加载过程:加载、验证、准备、解析、初始化。其中,验证、准备、解析三个过程统一称为连接。
加载
虚拟机在这个阶段完成三件事:
- 通过一个类的全定限名,获取这个类的二进行字节流。
- 将字节流所代表的静态存储结构转化为方法区的运行时数据结构。
- 在Java堆中生成一个代表这个类的对象,作为方法区数据访问的入口。
验证
验证阶段,虚拟机为了确保class文件的字节流信息符合当前虚拟机的要求,不会对虚拟机的安全产生威胁。
- 文件格式验证
- 元数据的验证
- 字节码验证
- 符号引用的验证
准备
准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,这些内存都将在方法区中进行分配。这里分配的变量(一般是指 被 static修饰的变量),而且这里初始值 是给0,若被设置了其他值,这个值具体值是在初始化阶段才会去赋值的。
解析
解析阶段是虚拟机将常量池的符号引用替换为直接引用的过程。
- 类或接口的解析
- 字段解析
- 类方法解析
- 接口方法解析
初始化
初始化是类加载过程的最后一步,根据赋值的实际值去初始化类变量和其他资源 。这一步完成之后,该类就可以被使用了。
要注意的是,初始化阶段有四种情况,会立即进行。
- 遇到new、 getstatic、 putstatic 或invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
- 使用java.lang.reflect包的方法对类进行反射调用的时候,如果没有进行过初始化,则需要先触发其初始化。
- 当初始化一个类的时候,如果其父类还没有进行初始化,需要先触发其父类的初始化。
- 当虚拟机启动时,用户指定一个要执行的主类(包含main的类),虚拟机会先初始化这个主类。
类加载器
双亲委派模型:如果一个类加载器收到了类的加载请求,它首先不会自己去加载这个类,而是把这个请求委派给自己的父类去加载,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会去加载。