Java 类的加载过程

Java 类的加载过程Java 类的加载过程当程序主动使用某个类时 如果该类还没有加载到内存中 则通过以下三个步骤对类进行加载初始化 类的加载 将类的 class 文件读入内存 并为之创建一个 java lang Class 对象到方法区中 此过程由类加载器完成类的链接 将类的二进制数据合并到 JRE 中类的初始化 JVM 负责对类进行初始化其中 类的链接可以分为以下几点 验证 确保加载的类符合 JVM 规范准备 正式为类变量 static 分配内存并设置类变量默认初始值的阶段 这些内存都将在方法区中进行分配解析 虚拟机常量

Java 类的加载过程

当程序主动使用某个类时,如果该类还没有加载到内存中,则通过以下三个步骤对类进行加载初始化:

  1. 类的加载:将类的class文件读入内存,并为之创建一个java.lang.Class对象到方法区中,此过程由类加载器完成
  2. 类的链接:将类的二进制数据合并到JRE中
  3. 类的初始化:JVM负责对类进行初始化

加载完之后还有两步为使用卸载,就是完整的类的生命周期。

加载

将类的文件信息加载到内存中,作为程序方法入口,分三步:

  1. 通过类的全限定名获取类的二进制字节流
  2. 将字节流的静态存储结构转化为方法去的运行时结构
  3. 在内存中生成Class对象,作为方法去入口

如果被加载的是一个数组类型,数组类型是一个比较特殊的类型,他不通过类加载器加载,而是由虚拟机去完成。但是他的引用却要考加载器加载,加载器会加载完数组的数据类型后将该数组绑定到相应的加载器上,然后与该类加载器一起绑定标识唯一性。

链接

其中,类的链接可以分为以下几点:

  1. 验证:确保加载的类符合JVM规范
  2. 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配,后续初始化时会实际赋值(实例变量会被分配到堆中)
  3. 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程)
符号引用替换为直接引用理解:

符号引用:比如一个类中引用了其它类,但是JVM不知道实际引用的其它类地址在哪,所以就会用符号引用来代表,等到解析的时候,再根据唯一符号引用去找其它类的地址。不止是其它类的代表,符号引用也可以代表方法,字段等。需要注意的是,符号引用与虚拟机布局无关,引用的目标不一定已经加载到内存中

直接引用:直接引用与虚拟机布局有关,如果使用直接引用,那么引用的目标一定已经加载到内存中

符号引用要转换成直接引用才有效,这也说明直接引用的效率要比符号引用高。那为什么要用符号引用呢?这是因为类加载之前,javac会将源代码编译成.class文件,这个时候javac是不知道被编译的类中所引用的类、方法或者变量他们的引用地址在哪里,所以只能用符号引用来表示,当然,符号引用是要遵循java虚拟机规范的。

初始化

  • 执行类构造器()方法的过程。类构造器()方法是由编译器自动收集所有类变量的赋值动作和静态代码块中的语句合并产生的。
  • 当初始化一个类的时候,会判断该类父类有没有初始化,如果没有则先触发父类的初始化
  • 虚拟机会保证一个类的()方法在多线程环境下的被正确加锁和同步

准备阶段中已经对类变量(static)进行内存分配,初始化时对类变量和静态代码块进行赋值和执行

类加载时机

  1. 创建类的实例,也就是一个new对象
  2. 访问某个类或接口的静态变量,或者对该静态变量赋值
  3. 调用类的静态方法
  4. 反射获取类信息
  5. 初始化一个类的子类(会首先初始化子类的父类)
  6. JVM启动时标明的启动类,即文件名和类名相同的那个类

类的加载机制

  1. 全盘负责:所谓全盘负责,就是当一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
  2. 双亲委派:所谓的双亲委派,则是先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载
  3. 缓存机制:缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓冲区中。这就是为很么修改了Class后,必须重新启动JVM,程序所做的修改才会生效的原因

双亲委派模型

类加载器分为:启动类加载器(BootStrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用类加载器(Application ClassLoader)、自定义类加载器。

如果一个类加载器收到了一个类加载的请求,它首先不会去加载类,而是去把这个请求委派给父加载器去加载,直到顶层启动类加载器,如果父类加载不了(不在父类加载的搜索范围内),才会自己去加载。

  1. 启动类加载器:加载的是lib目录中的类加载出来,包名是java.xxx(如:java.lang.Object)
  2. 扩展类加载器:加载的是lib/ext目录下的类,包名是javax.xxx(如:javax.swing.xxx)
  3. 应用程序扩展器:这个加载器就是ClassLoader的getSystemClassLoader的返回值,这个也是默认的类加载器。

双亲委派模型的意义在于不同的类加载器之间分别负责所搜索范围内的类的加载工作,这样能保证同一个类在使用中才不会出现不相等的类。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230441.html原文链接:https://javaforall.net

(0)
上一篇 2026年2月22日 下午6:01
下一篇 2026年2月22日 下午6:22


相关推荐

  • 在linux下显示中文目录和文件名

    在linux下显示中文目录和文件名

    2021年6月19日
    117
  • ASP.Net Core项目在Mac上使用Entity Framework Core 2.0进行迁移可能会遇到的一个问题….

    ASP.Net Core项目在Mac上使用Entity Framework Core 2.0进行迁移可能会遇到的一个问题….

    2022年3月13日
    56
  • cmd ping命令大全_ping命令怎么使用

    cmd ping命令大全_ping命令怎么使用简介:ping是一种Computernetworktools(电脑网络工具),作用是测试数据包是否能通过IP协议到达特定主机。Ping是Windows系统、Unix系统和Linux系统下的一个命令。它也属于一个通信协议,是TCP/IP协议的一部分。利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。该命令还可以加许多参数使用。例如:-t,-l,-n。(注意,所有ping指令都必须在知道IP的情况下使用)使用方法:主要的用法:1.-t:不断向目标IP发送数.

    2026年2月13日
    4
  • 图解原型和原型链

    图解原型和原型链前言知识 结论 原型 把一个函数称为类的话 原型就是每个类都有的属性 作用 给这类添加属性 分为两类 显式原型 prototype 和隐式原型 proto 所有函数对象 Function 都有显式原型 所有对象 如 Object Function Array 等对象 都有隐式原型原型链 本质是链表 proto 相当于链表的指针 指向下一个对象 每个对象都有 proto 属性 它指向构造函数的 prototype 属性 构造函数的 prototype 属性的 proto 属性

    2025年9月27日
    4
  • 树莓派连接wifi教程[通俗易懂]

    树莓派连接wifi教程[通俗易懂]第一种方法:如果你已经连接了VNC图形界面,就像手机电脑一样点击wifi的图标找到你的wifi输入密码就行第二种方法:如果登录了putty1.输入sudonano/etc/wpa_supplicant/wpa_supplicant.conf2.在尾部添加network={ssid=""psk=""}引号内容SSID是你的无线名称PSK是你的无线密码无线名称不能是中…

    2022年4月28日
    358
  • csgo开箱网站都有哪些_csgo官方承认的开箱网站

    csgo开箱网站都有哪些_csgo官方承认的开箱网站csgo开箱网站有哪些?csgo开箱网站大全以下国内知名CSGO开箱网站网站状态优惠码/推广码官网直达链接直接取回csgogoincsgo直接取回csgogoskinsdog直接取回csgo88hash直接取回csgogoskskins直接取回csgofateskins可取回暂无yskins直接取回csgocoolkaixiang可取回csgogopiggycase以下国外知名CSGO开箱网站

    2022年10月6日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号