类加载机制
约 655 字大约 2 分钟
2025-10-05
java 程序编译为.class文件,类加载就是从.class文件中的二进制数据读入内存中,将其存放在运行时方法区内,然后在堆区中创建一个java.lang.Class对象
从.class加载的类存放在元空间中(JDK1.8 前为方法区),而当程序中使用new()创建对象实例时,对象实例将以元空间的类作为模板创建,存放在[[内存结构#堆]]中
流程
加载
使用类加载器将二进制文件加载至内存中 -> 将字节码解析为 JVM 可识别的内部数据结构 -> 创建一个class对象表示该类
链接
验证
- 文件格式验证,是否符合
class文件规范 - 元数据验证,对字节码描述的信息进行语义分析,确保其符合 Java 语言规范
- 字节码验证,通过数据流和控制流分析,确定程序的语义是合法的
- 符号引用验证:确保解析动作能正确执行
准备
为类的静态变量分配内存并初始化为默认值 若某一变量同时被static与final修饰且被显式的赋予了初始值,那么在该阶段将会直接为其赋予该值,如
final int num = 10;若该变量的初始值并没有被显式赋予,那么依旧会被初始化为默认值,如
final int num = getValue();解析
将类中的符号引用转换为直接引用,即将字节码中的逻辑引用转换为直接指向目标指针、相对偏移量或一个间接定位到目标的句柄
初始化
执行类构造器方法,为静态变量赋值与静态代码块执行
双亲委派
- Bootstrap ClassLoader(启动类加载器):C/C++实现,JVM 内核的一部分 ^c99300
- Extension ClassLoader(扩展类加载器):父类是
Bootstrap,用于加载JAVA_HOME/lib/ext或java.ext.dirs指定的扩展包 - Application ClassLoader(应用类加载器 / 系统类加载器):父类是
Extension,负责加载用户路径Classpath上的类库 当一个类需要加载时,会委托自己的父类加载器去尝试加载,形成自底向上检查,再自顶向下加载
加载
MyClass类 由Application负责,向上委托给ExtensionExtension向上委托给BootstrapBootstrap不能找到该类,返回失败,责任落到Extension中Extension也找不到该类,返回失败,责任落到Application中 若Application中也找不到,那么将会抛出ClassNotFoundException
