您的位置:首页 > 健康 > 美食 > 沈阳比较有名的工装公司_长春网站seo_外贸营销网站建站_海南百度总代理

沈阳比较有名的工装公司_长春网站seo_外贸营销网站建站_海南百度总代理

2025/4/7 20:35:59 来源:https://blog.csdn.net/LeonNo11/article/details/147013277  浏览:    关键词:沈阳比较有名的工装公司_长春网站seo_外贸营销网站建站_海南百度总代理
沈阳比较有名的工装公司_长春网站seo_外贸营销网站建站_海南百度总代理

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


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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com