Class文件从硬盘到内存的心路历程
0x00 加载
- 类的加载本质上是由类加载器将字节码转换为
java.lang.Class
对象的过程 - 除了引导类加载器之外,所有的类加载器都有一个父类加载器
- 每一层的类加载器在收到加载请求之后,会将请求委派给父加载器执行;只有父加载器无法完成加载请求的时候,子加载器才尝试自己加载
- 这种双亲委托模型一方面避免了类的重复加载,另一方面还能防止Java 核心API被子加载器替换带来的隐患
0x01 链接
- 链接分为三步:验证、准备和解析。其本质上是将字节码合入JVM运行时的过程。
- 验证阶段主要是确认字节码结构的合法性,一旦验证失败,JVM会抛出
java.lang.VerifyError
异常 - 准备阶段主要是将Java类的静态域初始化为默认值(并不执行任何代码)
- 解析阶段主要是确保所有引用的类能被正确的找到,这通常会导致引用类被加载
0x02 初始化
该阶段的任务主要是初始化静态域,以及执行静态块代码。一个类被初始化之前,其父类会被先初始化。关于这一点,有2个需要注意的地方:
- 通过Java反射API也可能造成类的初始化
- 当访问一个类的静态域时,只有真正声明这个域的类才会被初始化。则,考虑如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
如上所述,上述代码的运行结果为: