类的加载过程
1、类的加载
- 将 字节码文件( .class ) 读入到 JVM 所管理的内存中
- 将 字节码文件对应的类的数据结构 保存在方法区
- 最后生成一个与该类对应的 java.lang.Class 类型的对象 ( 在堆区 )
2、类的链接
- 连接是把已读入到内存的类的二进制数据合并到Java运行时环境(JRE)中去。
- 连接又分为三个阶段:验证、准备、解析。
- 验证:验保证类有正确的内部结构,并且与其它类协调一致如果JVM 检查到错误,就会抛出Error 对象。
类文件的结构检查: 确保文件遵循Java 文件的固定格式
语义检查: 确保类本身符合Java 语言的语法规定
字节码验证: 确保字节码流可以被JVM 安全地执行
- 准备: 在准备阶段,JVM 为类的静态变量分配内存,并设置默认值(byte 、short 、int 默认值都是 0,long 默认值是 0L,float 默认值是 0.0F,double 默认值是 0.0,boolean 默认值是 false,char 默认值是 \u0000, 引用类型的默认值是 null)。
- 解析: 将符号引用解析为直接引用
3、类的初始化
- 初始化阶段,JVM执行类的初始化语句,为静态变量赋予初始值
- 静态变量的初始化途径:在静态变量的声明处进行初始化,在静态代码块中进行初始化
- 初始化代码可能是(声明变量时的赋值语句): protected static int a = 100 ;也可以是(静态代码块):
static {
a = 10000 ;
}
- 类初始化的一般步骤
如果该类还没有被加载和连接,那么先加载和连接该类
如果该类存在直接父类,但该父类还未初始化,则先初始化其直接父类
如果该类中存在初始化语句,则依次执行这些初始化语句
- 类的初始化时机
JVM 只有在首次主动使用某个类或接口时才会初始化它
被动使用不会导致本类的初始化
诡异的问题 解析测试案例:
<