Java中的类加载 && 双亲委派
类加载是Java虚拟机(JVM)将类的字节码文件(.class)加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被JVM直接使用的Java类型的过程。
类加载的过程
类加载过程主要分为以下三个阶段:
- 加载(Loading)
- 通过类的全限定名获取定义此类的二进制字节流
- 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
- 链接(Linking)
- 验证(Verification):确保加载的类信息符合JVM规范,没有安全方面的问题
- 准备(Preparation):为类变量(static变量)分配内存并设置默认初始值
- 解析(Resolution):将常量池内的符号引用转换为直接引用
- 初始化(Initialization)
- 执行类构造器<clinit>()方法的过程
- 该方法由编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生
类加载器(ClassLoader)
Java中的类加载器采用双亲委派模型(Parents Delegation Model),主要有以下几种:
- Bootstrap ClassLoader(启动类加载器)
最顶层的加载器,由C++实现,负责加载<JAVA_HOME>\lib目录下的核心类库
- Extension ClassLoader(扩展类加载器)
负责加载<JAVA_HOME>\lib\ext目录下的类库
- Application ClassLoader(应用程序类加载器)
也称为系统类加载器,负责加载用户类路径(ClassPath)上的类库
- 自定义类加载器
用户可以通过继承java.lang.ClassLoader实现自己的类加载器
双亲委派模型
工作流程:
- 当一个类加载器收到类加载请求时,首先不会自己尝试加载,而是委派给父类加载器
- 只有当父类加载器反馈无法完成加载请求时,子加载器才会尝试自己加载
优点:
- 避免类的重复加载
- 保证Java核心API的安全性和稳定性