Java类加载核心分加载、验证、准备、解析、初始化五阶段,按序开始但可交叉执行;验证/准备/解析合称链接;初始化是唯一用户代码介入阶段,执行静态变量赋值与静态块。

Java 中类加载过程核心分为五个阶段:加载、验证、准备、解析、初始化。这五个阶段按顺序开始,但执行过程可能交叉;其中验证、准备、解析合称“链接(Linking)”阶段。初始化是唯一允许用户代码介入的阶段,也是静态变量赋值和静态代码块真正执行的环节。
加载:把字节码读进内存并生成 Class 对象
这是整个流程的起点,由类加载器(ClassLoader)完成,主要做三件事:
- 通过类的全限定名(如 java.util.ArrayList)获取其二进制字节流——来源可以是本地 .class 文件、JAR/WAR 包、网络、数据库,甚至动态生成(如 CGLIB)
- 将字节流中的静态结构(比如常量池、字段表、方法表)转换为方法区(或元空间)中的运行时数据结构
- 在堆内存中创建一个 java.lang.Class 对象,作为该类元数据的访问入口
验证:确保字节码安全合规
防止恶意或损坏的 class 文件危害 JVM 运行环境,分四步校验:
- 文件格式验证:检查魔数、版本号、常量池等是否符合 class 文件规范
- 元数据验证:语义分析,比如是否继承了 final 类、是否重写了 final 方法
- 字节码验证:对方法体进行数据流分析,确保操作不会越界、类型匹配、跳转合法
- 符号引用验证:确保解析阶段能正常找到被引用的类、字段、方法
准备与解析:分配内存并处理符号引用
这两个阶段紧密关联,常被一起理解:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 准备:为类变量(static 变量)分配内存,并设默认值(如 int → 0,Object → null),注意此时不执行赋值语句(如 static int x = 123; 的 123 还没赋)
- 解析:将常量池内的符号引用(如类名、方法名、字段描述符)替换为直接引用(如内存地址、偏移量)。它不一定在初始化前完成——支持运行时动态绑定(如接口方法调用、invokedynamic)时,可延迟到首次使用时才解析
初始化:执行静态代码,真正“活起来”
这是类加载过程中唯一由程序员可控的阶段,触发条件明确,执行逻辑严格:
- 当遇到 new、getstatic、putstatic、invokestatic 字节码指令,且类未初始化时(例如:首次 new 实例、读写静态字段、调用静态方法)
- 使用反射(如 Class.forName())主动加载类
- 初始化子类时,若父类未初始化,则先触发父类初始化
- JVM 启动时指定的主类(含 main 方法的类)会最先初始化
- 执行顺序:先执行父类 <clinit>,再执行子类;同一类中,按源码中出现顺序依次执行静态变量赋值和静态代码块
使用和卸载属于类生命周期后续阶段,不属于“类加载过程”本身。整个加载机制背后有双亲委派模型保障类的唯一性和安全性,而各阶段细节决定了类何时可用、为何报 NoClassDefFoundError 或 ExceptionInInitializerError 等问题。

















