类加载机制和双亲委派
Java的类加载机制是JVM的核心功能之一,理解类加载过程对于理解Java程序运行机制非常重要。
核心问题
类加载的五个阶段
加载(Loading)
- 通过类的全限定名获取类的二进制字节流
- 将字节流转换为方法区的运行时数据结构
- 在内存中生成Class对象
验证(Verification)
- 文件格式验证
- 元数据验证
- 字节码验证
- 符号引用验证
准备(Preparation)
- 为类变量分配内存
- 设置默认初始值
解析(Resolution)
- 将常量池中的符号引用替换为直接引用
初始化(Initialization)
- 执行类构造器
<clinit>()方法 - 初始化类变量和静态代码块
- 执行类构造器
双亲委派模型
类加载器的层次结构:
- Bootstrap ClassLoader:加载核心类库(rt.jar)
- Extension ClassLoader:加载扩展类库
- Application ClassLoader:加载应用类路径下的类
双亲委派机制:
- 类加载器收到加载请求
- 先委托给父类加载器
- 父类加载器无法加载时,才由自己加载
优点:
- 避免类的重复加载
- 保证核心类的安全性
打破双亲委派
- 使用线程上下文类加载器(Thread Context ClassLoader)
- 实现自定义类加载器,重写loadClass方法
- SPI机制(Service Provider Interface)
常见面试题
为什么要使用双亲委派模型?
- 保证类的唯一性
- 保护核心类不被篡改
- 提高类加载效率
如何自定义类加载器?
- 继承ClassLoader类
- 重写findClass方法
- 定义类的加载逻辑
什么情况下会打破双亲委派?
- SPI机制
- OSGi框架
- 热部署场景