JVM 类加载的过程&类加载器&双亲委派机制

Java 类加载过程分为:加载 → 验证 → 准备 → 解析 → 初始化,其中前四步称为"连接(Linking)"。

文章目录

一、每一步JVM都在做什么?

1. 加载(Loading)------ 把字节码"搬进 JVM"

JVM 做的事:

  • 根据类的全限定名

  • 找到 .class 文件

  • 读入方法区(元空间)

  • 创建 Class 对象

来源可能是:

  • 本地 class 文件

  • jar 包

  • 网络

  • 动态生成(代理类)

⚠️ 这一步 还没执行任何 Java 代码


2. 验证(Verification)------ JVM 的"安检门"

目的:保证字节码是合法、安全的

主要验证内容:

  • 文件格式验证

  • 元数据验证

  • 字节码验证

  • 符号引用验证

如果失败:

java 复制代码
java.lang.VerifyError

3. 准备(Preparation)------ 给"类变量"分配空间

关键点(高频考):

  • 只给 static 变量 分配内存

  • 默认值

java 复制代码
static int a = 10;

准备阶段结果:

java 复制代码
a = 0

4.解析(Resolution)------ 把"符号引用"变成"直接引用"

  • 常量池里的符号引用

  • 转成内存地址

比如:

  • 方法

  • 字段

⚠️ 有些 JVM 会 延迟到真正使用时才解析


5. 初始化(Initialization)------ 真正执行 Java 代码

这是 唯一会执行 Java 代码的阶段

做的事:

  • 执行 <clinit> 方法

    • static 变量显式赋值

    • static 代码块

示例:

java 复制代码
static int a = 10;
static {
    a = 20;
}

初始化后:

java 复制代码
a = 20

二、类什么时候会被初始化?

会触发初始化的场景:

  1. new 对象

  2. 访问静态变量(非 final)

  3. 调用静态方法

  4. 反射

  5. 初始化子类,父类先初始化

  6. JVM 启动时的主类


不会触发初始化的场景(陷阱)

java 复制代码
public static final int A = 10;
  • 编译期常量

  • 不会触发类初始化


三、 父子类加载顺序(常考)

java 复制代码
class Parent {
    static {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    static {
        System.out.println("Child");
    }
}
java 复制代码
new Child();

输出:

复制代码
Parent
Child

规则:

先父后子,静态优先


四、类加载器和双亲委派机制

虽然不是"过程的一步",但几乎必追。

类加载器层级:

  • Bootstrap

  • Extension

  • Application

  • 自定义

双亲委派作用:

  • 防止核心类被篡改

  • 保证类唯一性

相关推荐
Codiggerworld2 小时前
JVM内存模型——你的对象住在哪里?
jvm
马猴烧酒.4 小时前
【面试八股|JVM虚拟机】JVM虚拟机常考面试题详解
jvm·面试·职场和发展
2301_790300965 小时前
Python数据库操作:SQLAlchemy ORM指南
jvm·数据库·python
m0_736919106 小时前
用Pandas处理时间序列数据(Time Series)
jvm·数据库·python
_F_y6 小时前
C++重点知识总结
java·jvm·c++
爱学习的阿磊7 小时前
使用Fabric自动化你的部署流程
jvm·数据库·python
m0_550024637 小时前
持续集成/持续部署(CI/CD) for Python
jvm·数据库·python
云姜.8 小时前
线程和进程的关系
java·linux·jvm
heartbeat..8 小时前
JVM 性能调优流程实战:从开发规范到生产应急排查
java·运维·jvm·性能优化·设计规范
玄同7658 小时前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱