当前位置: 首页 > news >正文

Java类加载问题

Java 类加载是 Java 虚拟机(JVM)在运行时动态加载 .class 文件到内存的过程。这个过程和类的生命周期紧密相关。我们来系统地学习下 Java 类加载的 过程生命周期阶段类加载器的作用 以及 相关细节和面试点


🧩 一、类加载过程(Class Loading Process)

Java 类从 .class 文件变成 JVM 可执行的对象代码,会经过 七个步骤,可以分为三大阶段:

✅ 加载 -> 连接 -> 初始化:

加载(Loading)
 ↓
验证(Verification)
 ↓
准备(Preparation)
 ↓
解析(Resolution)
 ↓
初始化(Initialization)
 ↓
使用(Using)
 ↓
卸载(Unloading)

🧠 二、七大生命周期阶段详解:

1. 加载(Loading)

  • 干什么: 找到 .class 文件并读取其字节流。
  • 由谁干: 类加载器(ClassLoader)。
  • 从哪来: 本地磁盘、网络、JAR 包等。
  • 结果: 生成 java.lang.Class 类的实例。

2. 验证(Verification)

  • 干什么: 验证字节码是否合法、符合 JVM 规范。
  • 为什么要: 防止恶意或错误的类破坏 JVM 安全。
  • 检查什么: 魔数、常量池、方法结构、控制流。

3. 准备(Preparation)

  • 干什么: 为类的静态变量分配内存,并设置默认初始值(不会执行初始化赋值)。
  • static int a = 5;
    // 在这阶段,a 分配了内存,值为 0,不是 5
    

4. 解析(Resolution)

  • 干什么: 将常量池中的符号引用(Symbolic Reference)替换成直接引用(Direct Reference)。
  • 如: 把类名 "java/lang/Object" 转成真实的类对象。
  • ⚠️:可能在运行时延迟解析(lazy resolve)。

5. 初始化(Initialization)

  • 干什么: 执行类中的 <clinit>() 方法(静态代码块和静态变量初始化)。
  • 初始化顺序:
    1. 父类先初始化;
    2. 子类再初始化;
    3. 静态变量和静态代码块按出现顺序执行。

6. 使用(Using)

  • 实例化对象、调用方法、访问字段 都属于使用阶段。

7. 卸载(Unloading)

  • 何时: 某个类对应的 ClassLoader 被 GC 回收,并且该类无任何实例。
  • 注意: JVM 很少卸载类,通常用于动态模块或热部署。

🎯 三、类加载器(ClassLoader)

Java 使用双亲委派模型

BootstrapClassLoader(引导类加载器)
   ↑
ExtClassLoader(扩展类加载器)
   ↑
AppClassLoader(应用类加载器)
   ↑
自定义ClassLoader(如 SPI、插件等)

🚀 加载器加载顺序(查找顺序):

  1. 请求父加载器先加载;
  2. 如果父加载器找不到,再由当前类加载器尝试加载;
  3. 保证核心类不会被覆盖(比如你写一个 java.lang.String 也不会被加载)。

📌 四、常见类加载时机(何时触发加载)

  1. new 对象时
  2. 访问静态字段或方法
  3. 使用 Class.forName()
  4. 子类初始化时会先初始化父类
  5. 反射调用类成员时
  6. 启动主类时

❗ 五、面试重点&易错点:

内容
类何时初始化?有静态变量/静态代码块时且被访问
类何时不会初始化?引用数组不会触发类初始化
<clinit>() 和构造器区别?<clinit>() 是类初始化,构造器是对象初始化
自定义 ClassLoader 作用?动态加载模块、热更新、插件系统
双亲委派有什么好处?安全、避免重复加载

🧪 小练习题:

class A {
    static {
        System.out.println("A static block");
    }
}
public class Test {
    public static void main(String[] args) {
        A[] arr = new A[10]; // 会不会输出 A static block?
    }
}

✅ 不会,因为只是创建了数组,没有初始化类 A


如果你想我配张图解释类加载的阶段,或者深入讲讲某个阶段的底层原理(比如常量池解析),我也可以继续展开。要不要?

http://www.dtcms.com/a/113324.html

相关文章:

  • STM32单片机入门学习——第16节: [6-4] PWM驱动LED呼吸灯PWM驱动舵机PWM驱动直流电机
  • 《AI大模型应知应会100篇》第4篇:Transformer架构深入浅出:大模型的基石
  • cadence17.4和16.6同时安装无法使用的问题
  • 关于图片分类任务的猜想 | 撰写论文 paper
  • .net多贸易公司借入借出归还设备进销存管理系统软件租金计算库存管理
  • M芯片,能运行普通应用程序的原架构虚拟机
  • Java的Selenium元素定位-xpath
  • LeetCode热题100记录-【二叉树】
  • 【Deep Reinforcement Learning Hands-On Third Edition】【第1章:什么是强化学习】
  • 《海空重力测量理论方法及应用》之一重力仪系统组成及工作原理(下)
  • qt designer 软件主题程序设计
  • Python精进系列:从 __name__ 开始了解 python 常见内置变量
  • synchronized 锁升级机制详解
  • ROS2 多机时间同步(Chrony配置简明指南)
  • docker本地部署anythingllm
  • C++重载运算符的本质
  • 将 DataFrame 中某一列的列表拆分成多个独立的列的方式
  • Linux上位机开发实践(做一专多能的方案提供者)
  • 从情感分析到朴素贝叶斯法:基于朴素贝叶斯的情感分析如何让DeepSeek赋能你的工作?
  • 【Kubernetes】RBAC(基于角色的访问控制)如何设置?如何管理 Kubernetes 的权限?
  • MCP 极简入门 - 三分钟 Cline + Smithery 运行 time 服务
  • HTTP/2:新一代网络协议的变革与优势
  • 借 DCMM 东风,提升数据管理价值生产力
  • BugKu Simple_SSTI_2
  • 【UE5 C++课程系列笔记】31——创建Json并保存为文件
  • 横扫SQL面试——TopN问题
  • 团体设计程序天梯赛L2-025 # 分而治之
  • Maven使用
  • 3535 数组分割
  • Python 数据库选型指南(架构师视角)