1.类加载的时机
①类的声明周期:加载、验证、准备、解析、初始化、使用、卸载7个阶段
2.加载
①完成3件事情:
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口
3.验证
①文件格式验证
- 是否以魔数0xCAFEBABE开头
- 主、次版本号是否在当前虚拟机处理范围内
- 常量池的常量中是否有不被支持的常量类型
- 指向常量的各种索引值是否有指向不存在或不符合类型的常量
- CONSTANT_Utf8_info型的常量是否有不符合UTF8编码的数据
- Class文件中各个部分及文件本身是否有被删除的或附加的其他信息
- ……
②元数据验证
- 这个类是否有父类
- 这个类的父类是否继承了不允许被继承的类
- 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法
- 类中的字段、方法是否与父类产生矛盾
- …….
③字节码验证
④符号引用验证
4.准备
①准备阶段正式为类变量分配内存并设置类变量初始值的阶段
②这里所指的初始值“通常情况下”是数据类型的零值
③基本数据类型的零值
数据类型 | 零值 |
---|---|
int | 0 |
long | 0L |
short | (short)0 |
char | ‘\u0000’ |
byte | (byte)0 |
boolean | false |
float | 0.0f |
double | 0.0d |
reference | null |
④如果类字段的字段属性表中存在ConstantValue属性,那么在准备阶段变量value就会被初始化为ConstantValue属性所指向的值
5.解析
①解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程
②符号引用:符号引用以一组符号来描述所引用的目标
③直接引用:直接引用可以直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄
6.初始化
7.类与类加载器
①类加载器用于实现类的加载动作
8.双亲委派机制
①启动类加载器:
- 使用C++语言实现
- 启动类加载器负责将存放在JAVA_HOME\lib目录中,或者被-Xbootclasspath参数所指定的路径中
②扩展类加载器
- 负责加载JAVA_HOME\lib\ext目录中的,或者被java.ext.dirs系统变量所指定路径中的所有类库
③应用程序类加载器
- 负责加载用户路径classpath上所指定的类库