今天继续类加载的学习,先复习下类的生命周期。
上一篇讲到了阶段2-验证JVM系列(7)-JVM类加载机制(1),今天从阶段3开始。
阶段3:准备
准备阶段都做什么呢?主要做两件事情:
1)为类变量分配内存
什么是类变量?也就是用static修饰的变量;在哪个区域上分配?在方法区上分配,记住是方法区而不是堆。
2)设置类变量初始值
比如public static int value = 111;设置变量初始值,是不是就是将value设置为111呢?不是。变量value在准备阶段后设置的初始值是0。将value设置为111的操作是在初始化阶段进行。
如果我想将类变量value在初始话阶段就初始化为123,该怎么办呢?
答:public static final int value = 111;加上final关键字即可。
阶段4:解析
解析过程就是虚拟机将符号引用替换为直接引用的过程。
符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到了内存中;直接引用和虚拟机实现的内存布局相关,如果有了直接引用,那么引用的目标一定已经加载到了内存中。
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符7类符号引用进行。
阶段5:初始化
类加载的最后一步就是初始化了,前4个阶段都没有执行Java代码,都是在加载、验证、准备、解析,并不涉及执行程序代码,初始化阶段才真正涉及到执行编写的Java代码。
我们知道在准备阶段已经初始化过一次值,但准备阶段的初始化是JVM设置的默认值,阶段5的初始化是按程序员的程序设置进行初始化的。
类与类加载器
比较两个类是否相等,是在这两个类由同一个类加载器加载的前提下进行,如果同一个类的class文件由两个不同的类加载器加载,那么这两个类不会相等。
双亲委派模型
双亲委派模型就是下图所示的加载器关系,要求除了启动类加载器,其余的类加载器都有自己的父类加载器。
工作过程是:如果一个类收到了类加载请求,它并不会马上自己去加载这个类,而是把这个请求先委派给父类加载器去加载;只有当父类加载器反馈说我加载不了,子加载器才尝试去加载这个类。
Good night ^_^,明天继续