一、概述
1、 类加载器子系统负责从文件系统或者网络中加载.Class文件
2、classloader只负责类的加载,至于他是否能够运行由执行引擎来决定
3、加载的类的信息会存放在方法区(元空间)中
二、加载过程
1、加载阶段
1、通过一个类的全限定名来获得该类的二进制字节流
2、将该字节流所代表的静态存储结构转化为方法区的运行时数据结构
3、在内存中生成一个java.lang.Class对象,作为方法区对这个类的各种数据的访问入口
2、链接阶段
- 验证:验证字节码文件是否合法:
- 文件格式验证
- 元数据验证
- 字节码验证
- 符号引用验证
- 准备:
- 为类变量分配内存并进行初始化,此时初始化的为零值
- 对于final修饰的类变量,在编译阶段就已经完成了内存的分配,此时会对该变量进行初始化
- 这里并不会为实例变量进行初始化,类变量会分配在方法区中,而实例变量会随着对象一起分配到堆中
- 解析:将常量池中符号引用转换为直接引用
3、初始化阶段
- 此阶段会按顺序收集静态变量与静态代码块中的内容到<clinit>()方法中进行类变量的初始化
- 若该类有父类,会保证该类父类的<clinit>()先执行
- 虚拟机必须保证一个类的<clinit>()方法在多线程下被同步加锁
三、类加载器
- 引导类加载器(Bootstrap_ClassLoader)
- 由C/C++编写,并嵌入在JVM中
- 该类没有父类加载器
- 该类用于加载java的核心类库
- 扩展类加载器(Extension_ClassLoader)
- 该类派生于ClassLoader(是一个抽象类)
- 该类用于加载java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jre/lib/ext子目录下加载类库
- 系统类加载器(APPClassLoader)
- 派生于ClassLoader
- 该类用于加载用户自定义类
- 自定义类加载器
四、双亲委派机制
一、过程
当类加载器接受到一个类加载请求时,并不会直接对该类进行加载,而是会将该请求委派给上一级的加载器。
向上逐层委派到引导类加载器后,由引导类加载器判断自己是否有权限加载该类,有则加载后直接返回,没有则交付给下一层扩展类加载器,扩展类加载器查看自己是否有权限加载该类,有则直接加载后返回,没有则向下继续交付给系统类加载器处理
二、优点
1、保证每个类只被加载一次
2、保护java的核心代码