类的加载和初始化 ---- new 一个对象时,在JVM 中的过程是什么
在程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三个步骤来对该类进行初始化。如果没有意外,JVM 将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或类初始化。
类的加载
类加载指的是将类的 class 文件读入内存,并为之创建一个 java.lang.Class 对象,也就是说,当程序中使用任何类时,系统都会为之建立一个 java.lang.Class 对象。
类的加载由类加载器完成,类加载器通常由 JVM 提供,这些类加载器负责将 .class 文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成一个 java.lang.Class 对象。
类的连接
当类被加载之后,系统为之生成一个对应的 Class 对象,接着将会进入连接阶段,连接阶段负责把类的二进制数据合并到 JRE 中。
类的连接又可分为如下三个阶段:
- 验证:这阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。
- 准备:类准备阶段负责为类变量分配内存,并设置默认初始值。
- 解析:将类的二进制数据中的符号引用替换成直接引用。
类的初始化
在类的初始化阶段,虚拟机负责对类进行初始化,主要就是对类变量进行初始化。对类变量指定初始值有两种方式:
- 声明类变量时指定初始值;
- 使用静态代码块为类变量指定初始值。
小总结
JVM 初始化一个类包含如下几个步骤:
- 假如这个类还没有被加载和连接,则程序先加载并连接该类。
- 假如该类的直接父类还没有被初始化,则先初始化其直接父类。
- 假如类中有初始化语句,则系统依次执行这些初始化语句。
当执行第 2 个步骤时,系统对直接父类的初始化步骤也是遵循 1~3 步骤;如果改直接父类又有直接父类,系统再次重复这三个步骤来初始化这个父类......以此类推,所以 JVM 最先初始化的总是 java.lang.Object 类。这个策略也称之为双亲委派策略。
类初始化的时机
当 Java 程序首次通过下面 6 种方式来使用某个类或接口时,系统就会初始化该类和接口。
- 创建类的实例。包括:使用 new 来创建实例;通过反射来创建实例,通过反序列化的方式来创建实例。
- 调用某个类的类方法(静态方法)。
- 访问某个类或接口的类变量,或为该类变量赋值。
- 使用反射来强制创建某个类或接口对应的 java.lang.Class 对象。
- 初始化某个类的之类。初始化某个类的子类时,该子类的所有父类都会被初始化。
- 直接使用 java.exe 命令来运行某个主类。当运行某个主类时,程序会先初始化该主类。
【特别注意】
对于一个 final 型的类变量,如果该类变量的值在编译时就能确定下来,这个类变量就是 “宏变量”,Java 编译器会直接这个类变量出现的地方直接替换成它的值(相当于使用了常量)。因此程序在使用该静态类变量时,并不会导致该类的初始化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)