本篇将介绍类加载过程中的一些小细节
类加载过程
Loading
- 我们以前在提到Loading的时候就简单地说Loading过程就是将class文件加载到内存,其实这里面还是存在一些细节的
- 通过类的全限定名将class的二进制文件加载到内存
- 将class文件中的静态数据结果转换为运行时数据区的结构
- 生成一个class对象存入内存
Verification
我们以前提到Verification只是简单地提了一下,说这个过程会对类进行检验,但是其实Verification过程是整个类加载过程中消耗时间最长的,我们来稍微详细地介绍一下
文件格式验证
验证魔数是否是CAFEBABE
验证class文件的版本(如果当前JVM的版本低于class文件的版本,那么直接拒绝)
常量池进行检测
………
可以说,文件格式验证有非常多的部分,这里仅仅只是列出了九牛一毛,感受一下文件格式验证过程到底在干什么事
元数据验证
这个类是否有父类(除了Object,所有类都应该有父类)
这个类是否继承了不允许继承的类(被final修饰的类)
这个类是否实现了这个类实现的接口的所有方法(或者父类中的抽象方法)
………
元数据验证过程就是为了检测class文件中是否存在违背《Java语言规范》中的规定,也就是大家俗称的语法检验
字节码检验
这个过程是整个Verification过程中最最复杂的验证环节,保证被验证的class文件会不会做出对JVM产生危害的举动,例如
把一个子类对象赋值给父类,这是允许的,但是不允许把一个父类对象赋值给一个子类对象
防止在操作数栈中放入一个 int 但是却在本地变量表中存入的是long类型
………
字节码验证并不是万能的,只能说没有通过字节码验证一定是有错误的;通过了字节码验证也不能保证一定正确
符号引用验证
这个符号引用的全限定名是否可以找到对应的类
符号引用指向的类的权限修饰符(access_flag)是否能够被允许访问(例如不在同一个包内,那么private是不允许访问的)
………
Preparation
- 这个阶段就是将类中的静态变量赋予默认值,被final修饰的赋予初始值
Resolution
- 这个阶段要做的事情就是将常量池中的符号引用变成直接引用
Initialization
- 这个阶段是类加载的最后一个步骤,做的事情其实就是将一开始赋予了默认值的静态变量赋予初始值
- 这个过程其实是调用了
方法,这个方法其实没有什么,只要一个类拥有static{}语句块,或者初始化的赋值操作,那么 方法就会被创建,通过这个方法来对static静态变量赋予默认值
文档信息
- 本文作者:JunHua yin
- 本文链接:https://yin-JH.github.io/2021/04/09/%E9%98%85%E8%AF%BB-%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA-%E8%A1%A5%E5%85%85JVM%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB%E7%B3%BB%E5%88%97(%E4%B8%89)%E4%B9%8B%E7%B1%BB%E5%8A%A0%E8%BD%BD%E8%BF%87%E7%A8%8B%E4%B8%8E%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)