类加载:把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。
加载
通过类名获取类的二进制字节流
字节流转化为方法区的运行时数据结构
生成这个类的CLass对象
验证
确保Class的字节流包含的信息符合Java虚拟机规范
文件格式验证
是否魔数开头
检查常量
保证输入的字节流能正确地解析并存储于方法区之内
元数据验证
是否有父类
是否继承了不允许被继承的类
如果不是抽象类,是否实现了父类和接口的所有方法
字段和方法是否和父类有矛盾
对类的元数据信息进行语义校验
字节码验证
保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作
·保证任何跳转指令都不会跳转到方法体以外的字节码指令
符号引用验证
符号引用中通过字符串描述的全限定名是否能找到对应的类
指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段。
符号引用中的类、字段、方法的可访问性(private、protected、public、<package>)是否可被当前类访问。
准备
是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初 始值的阶段
解析
解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程
初始化
Java虚拟机才真正开始执行类中编写的Java程序代码,将主导权移交给应用程序。
使用
卸载
初始化场景
new关键字、读取或设置一个final静态字段、调用静态方法、反射、初始化子类会初始化父类
类加载器
Java虚拟机设计团队有意把类加载阶段中的“通过一个类的全限定名来获取描述该类的二进制字节 流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需的类。实现这个动作的代码被称为“类加载器”(Class Loader)。
双亲委派
:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加 载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的 加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请 求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。