回顾
上一篇说到了 Java是如何运行的
先从 java 文件 编译成 class 文件 通过 类加载机制 加载进 jvm虚拟机
然后,jvm 就可以执行我们的代码了
什么情况下会加载一个类
一个类从加载到应用,会经历如下几个步骤
加载 >> 验证 >> 准备 >> 解析 >> 初始化 >> 使用 >> 卸载
那么啥时候会加载到jvm虚拟机来呢?
答案就是在 代码里面使用的时候
从main方法开始执行,当执行到 2 的地方,会用到另外一个类,这个时候会触发JVM通过类加载机制,从这个类的class字节码文件中加载对应的类到内存中来使用
Java程序对类的使用方式可分为两种
1、主动使用(7种 ,以下为 6 种主流方式)
创建类的实例
访问某个类的接口或静态变量,或者对该静态变量赋值
调用类的静态变量方法
反射
初始化一个类的子类
被JVM启动时标明为启动类的类
2、被动使用
验证准备初始化过程
验证:依据JVM虚拟机规范,来校验你加载进来的 class 文件 中的内容 是否符合规范。
准备:为类的静态变量分配内存,将其初始化为默认值
解析阶段:将符号引用替换成直接引用
初始化:为类的静态变量赋予正确的初始值
双亲委派模型
JVM提供4种类加载器
1、根加载器:负责加载安装在机器上java核心目录下的核心类的 / lib
2、扩展类加载器:/lib/ext
3、应用加载器:负责加载ClassPash路径下的class文件,也就是环境变量指定路径的类
4、自定义加载器:根据自己的需求去加载要求的类
双亲委派机制是有亲子层级结构的,基于这套层级机构,会有一套双亲委派机制
假设我们有个类需要加载
这时会往上抛,交给自己我父加载器去加载,最终传到顶层
应用加载器 >> 扩展类加载器 >> 启动类加载器
如果父类加载器在自己我范围内,没有找到这个类
则会下推给自己的子类加载器去加载
启动类加载器 >> 扩展类加载器 >> 应用类加载器
一句话讲:就是先找父亲去加载,不行的话,再由儿子来加载
这样可以避免多层级的类加载器重复加载某些类