Class 文件和类加载机制

news2025/4/15 10:18:27

一、Class 文件 与 类加载机制 概述

什么是 Class 文件?

  • Java 源码(.java)经过 javac 编译器 编译生成的字节码文件(.class);
  • 由 JVM 识别执行,包含类的完整结构信息(如字段、方法、常量池、访问权限等);
  • 是平台无关的中间代码。

什么是类加载机制?

JVM 的操作对象是 Class 文件,JVM 把 Class 文件中描述类的数据结构加载到内存中,并对数据进行校验、解析和初始化,最终形成可以被 JVM 直接使用的类型,这个过程被称为类加载机制。

其中最重要的三个概念就是:类加载器、类加载过程和类加载器的双亲委派模型。

  • 类加载器:负责加载类文件,将类文件加载到内存中,生成 Class 对象。
  • 类加载过程:加载、验证、准备、解析和初始化。
  • 双亲委派模型:当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把请求委派给父类加载器去完成,依次递归,直到最顶层的类加载器,如果父类加载器无法完成加载请求,子类加载器才会尝试自己去加载。

二、类的生命周期

一个类从被加载到虚拟机内存中开始,到从内存中卸载,整个生命周期需要经过七个阶段:加载 (Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化 (Initialization)、使用(Using)和卸载(Unloading)。
在这里插入图片描述

  1. 加载(Loading):通过类加载器读取 .class 文件,生成 Class 对象。
  2. 连接(Linking)
    • 验证(Verify):校验 class 文件格式/安全性;
    • 准备(Prepare):为类变量(static)分配内存,设置默认值;
    • 解析(Resolve):将常量池中的符号引用转化为直接引用。
  3. 初始化(Initialization):执行静态变量赋值、静态代码块;
  4. 使用(Using):正常使用类的阶段;
  5. 卸载(Unloading):类被回收(通常很少发生)。

三、类的装载过程(详细流程)

类装载过程包括三个阶段:载入、连接(包括验证、准备、解析)、初始化。

1、载入:将类的二进制字节码加载到内存中。

2、连接可以细分为三个小的阶段:

  • 验证:检查类文件格式是否符合 JVM 规范
  • 准备:为类的静态变量分配内存并设置默认值。
  • 解析:将符号引用替换为直接引用。

3、初始化:执行静态代码块和静态变量初始化。

在准备阶段,静态变量已经被赋过默认初始值了,在初始化阶段,静态变量将被赋值为代码期望赋的值。

换句话说,初始化阶段是执行类的构造方法的过程。

载入过程JVM 会做什么?

在这里插入图片描述

  • 1)通过一个类的全限定名来获取定义此类的二进制字节流。
  • 2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  • 3)在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

四、类加载器有哪些?(ClassLoader)

类加载器(ClassLoader)用于动态加载 Java 类到 Java 虚拟机中。主要有四种类加载器:

1、启动类加载器(Bootstrap ClassLoader)负责加载 JVM 的核心类库,如 rt.jar 和其他核心库位于 JAVA_HOME/jre/lib 目录下的类。

2、扩展类加载器(Extension ClassLoader):由 sun.misc.Launcher$ExtClassLoader(或其它类似实现)实现。负责加载 JAVA_HOME/jre/lib/ext 目录下,或者由系统属性 java.ext.dirs 指定位置的类库。

3、应用程序类加载器(Application ClassLoader):由 sun.misc.Launcher$AppClassLoader(或其它类似实现)实现。

负责加载系统类路径(classpath)上的类库,通常是我们在开发 Java 应用程序时的主要类加载器。

我们编写的任何类都是由应用程序类加载器加载的,除非显式使用自定义类加载器。

4、用户自定义类加载器 (User-Defined ClassLoader),我们可以通过继承 java.lang.ClassLoader 类来创建自己的类加载器。

这种类加载器通常用于加载网络上的类、执行热部署(动态加载和替换应用程序的组件)或为了安全目的自定义类的加载方式。

类加载器加载范围
Bootstrap ClassLoader(启动类加载器)加载 JDK 的核心类,如 java.lang.*,用 C++ 编写,不是 Java 类
Extension ClassLoader(扩展类加载器)加载 jre/lib/ext 或指定目录下的扩展类
App ClassLoader(应用程序类加载器)加载 classpath 下的应用类
自定义 ClassLoader(用户自定义类加载器)程序员可自定义加载逻辑,通常用于插件机制、类隔离等

五、什么是双亲委派机制?

定义:

  • 类加载器在加载类时,先将请求委托给父加载器,父加载器无法加载时,子加载器才尝试加载。
  • 从上到下依次委托:App → Ext → Bootstrap
    在这里插入图片描述
  • 当一个类加载器需要加载某个类时,它首先会请求其父类加载器加载这个类。
  • 这个过程会一直向上递归,也就是说,从子加载器到父加载器,再到更上层的加载器,一直到最顶层的启动类加载器。
  • 启动类加载器会尝试加载这个类。如果它能够加载这个类,就直接返回;如果它不能加载这个类(因为这个类不在它的搜索范围内),就会将加载任务返回给委托它的子加载器。
  • 子加载器接着尝试加载这个类。如果子加载器也无法加载这个类,它就会继续向下传递这个加载任务,依此类推。
  • 这个过程会继续,直到某个加载器能够加载这个类,或者所有加载器都无法加载这个类,最终抛出 ClassNotFoundException。

好处:

  1. 避免重复加载:父加载器加载的类,子加载器无需重复加载。
  2. 核心类安全性:确保核心类不会被篡改(比如 java.lang.String只能由 Bootstrap ClassLoader 加载,防止被篡改。)

示例流程:

加载 java.lang.String → AppClassLoader → ExtClassLoader → Bootstrap → 成功加载


六、如何破坏双亲委派机制?

  1. 自定义 ClassLoader,重写 loadClass() 方法,不调用 super.loadClass()
  2. 使用第三方框架,如 Tomcat、JSP 容器、Spring Boot 的隔离加载;
  3. 常用于:热部署、插件隔离、多个版本并存 等场景。

总结:

问题回答
类加载器有哪些?Bootstrap、Ext、App、自定义
类的生命周期?加载 → 连接(验证/准备/解析)→ 初始化 → 使用 → 卸载
什么是双亲委派?类加载器先委托父类加载,父类无法加载才自己尝试加载
为什么要用双亲委派?避免重复加载,保护核心类安全
如何打破双亲委派?自定义类加载器,重写 loadClass() 方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3+Vite+TypeScript+Element Plus开发-07.Mockjs引用与Axios封装

系列文档目录 Vue3ViteTypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 Header响应式菜单缩展 Mockjs引用与Axios封装 登录设计 登录成功跳转主页 多用户动态加载菜单 Pinia持久化 动态路由-配置 文章目录 目录 系列文档目…

【Redis】背景知识

一、Redis的特性 Redis是一种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis中的值可以是由string(字符串),hash(哈希),list&#xf…

航电系统的任务载荷集成技术要点概述!

一、任务载荷集成技术难点 1. 接口标准化与兼容性 异构设备协议冲突:不同厂商的载荷设备(如光学相机、雷达、电子战模块)采用不同的通信协议(如1553B、RS422、以太网),需设计统一的总线接口标准以支持即…

OceanBase V4.3.5 上线全文索引功能,让数据检索更高效

近日,OceanBase 4.3.5 BP1 版本正式推出了企业级全文索引功能。该版本在中文分词、查询效率及混合检索能力上进行了全面提升。经过自然语言模式和布尔模式在不同场景下的对比测试,OceanBase 的全文索引性能明显优于 MySQL。 点击下载 OceanBase 社区版…

Qt中的信号与槽及其自定义

信号源:哪个控件发的信号 信号的类型:用户进行不同的操作就会触发不同的信号 如点击按钮,在输入框移动光标,勾选一个复选框,选 择一个下拉框 信号的处理方式:槽(slot)----也就是函数,Qt中用con…

【PFPGA学习】状态机思想编程HDLbitsFPGA练习

目录 一、用状态机实现LED流水灯 1.1状态机思想 1.2状态机思想LED流水灯 1.3 modesim仿真 1.4 FPGA烧录实现 二、CPLD和FPGA芯片 1. 核心结构与技术原理 2. 性能与容量 3. 适用场景 4. 选型建议 三、HDLbitsFPGA练习记录(combinational logic…

Android 中集成 Unity 工程的步骤

在 Adroid 项目中集成 Unity 工程,主要步骤如下: 一、前提条件 1、已有一个 Android 工程项目; 2、Unity 工程已导出为 Android 工程,目录大概如下: 二、集成步骤 1、在 Android 工程中导入 Unity 工程的 unityLibrary 模块。 在 Android Studio 中,点击菜单栏 Fil…

Python从入门到精通全套视频教程免费

概述 📢 所有想学Python的小伙伴看过来!作为深耕编程领域的技术分享者,最新整理了一份Python从0到1的视频教程。 💡亮点 ✅ 保姆级系统路线:从环境搭建、语法精讲,到爬虫/数据分析/AI/Web全栈开发&#…

蓝桥杯:对字符串处理常用知识笔记

一、前面四个是计算带有空格字符串的的长度计算 C语言代码 #include<string.h> #include<stdio.h> int main() { char s[105]; gets(s); printf("%d", strlen(s)); return 0; } 算法2 C 代码&#xff08;常用&#xff09; #include <iostream> #in…

实现一个 Markdown 编辑器组件:Vue 3 + Vite + Highlight.js

文章目录 一、项目背景与需求分析二、搭建基础项目1. 初始化 Vue 3 项目2. 安装依赖 三、实现 Markdown 编辑器组件1. 创建 Markdown 编辑器组件2. 组件说明 四、优化与拓展1. 自动保存功能2. 文件上传功能 五、总结 一、项目背景与需求分析 在现代前端开发中&#xff0c;Mark…

帆软fvs文件中某表格新增数据来声提醒

1.上传音频文件到帆软安装目录的指定环境 准备一个音频文件&#xff08;如 mp3 格式&#xff09;&#xff0c;并将其放置在合适的目录。 例如&#xff1a;%FR_HOME%\webapps\webroot\help 2.点击 FVS 模板左上角「模板>页面加载结束事件」&#xff0c;输入以下 JavaScript …

从零用java实现 小红书 springboot vue uniapp (11)集成AI聊天机器人

前言 移动端演示 http://8.146.211.120:8081/#/ 管理端演示 http://8.146.211.120:8088/#/ 项目整体介绍及演示 前面的文章我们主要完成了基础模块的开发 这次我们跟一下热点 创建AI聊天机器人 并嵌入到我们的uniapp中 首先需要了解dify我已经完成了搭建win10 VMware安装ubuntu…

$_POST 超级全局变量

$_POST 是一个超级全局变量&#xff0c;在 PHP 中用于收集通过 HTTP POST 方法发送到服务器的数据。与 $_GET 不同&#xff0c;$_POST 允许发送大量数据&#xff0c;且数据不会显示在 URL 中&#xff0c;因此更适用于提交敏感信息&#xff0c;如用户登录信息、表单数据等。 使…

开发一个环保回收小程序需要哪些功能?环保回收小程序

废品分类展示与识别 详细分类列表&#xff1a;清晰展示常见废品类型&#xff0c;如废纸&#xff08;报纸、书本纸、包装纸等&#xff09;、塑料&#xff08;塑料瓶、塑料容器、塑料薄膜等&#xff09;、金属&#xff08;易拉罐、铁制品、铜制品等&#xff09;、玻璃&#xff0…

Debezium嵌入式连接postgresql封装服务

文章目录 1.项目结构&#xff1a;2.依赖&#xff1a;3.application.properties4.DebeziumConnectorConfig类5.TableEnum类6.TableHandler接口&#xff08;表处理抽象&#xff09;7.DefaultTableHandler默认实现类8.UserTableHandler处理类9.TableHandlerFactory工厂10.Debezium…

Python 爬取 1688.item_get_factory 接口:获取工厂档案信息实战指南

在电商采购和供应链管理中&#xff0c;了解供应商的工厂信息是至关重要的一步。1688 作为国内领先的 B2B 平台&#xff0c;提供了丰富的供应商和工厂档案信息。通过 item_get_factory API 接口&#xff0c;开发者可以获取工厂的详细信息&#xff0c;包括工厂名称、地址、联系方…

Rust所有权详解

文章目录 Rust所有权所有权规则作用域 内存和分配移动与克隆栈空间堆空间 关于函数的所有权机制作为参数作为返回值 引用与租借垂悬引用 Rust所有权 C/C中我们对于堆内存通常需要自己手动管理&#xff0c;手动申请和释放&#xff0c;即便有了智能指针&#xff0c;对于效率的影…

CExercise_07_1指针和数组_2数组元素的逆序数组逆序(指针版 reverse_by_ptr 和下标版 reverse_arr)

题目&#xff1a; 数组元素的逆序。要求使用[]运算符以及纯粹指针操作两种方式来完成。 关键点 arr[i] arr[len - 1 - i]; arr[0]arr[len-1]; 如果数组序列是偶数,则调换最中间一对为止;若为奇数,则单出一个不用反转. 思想就是长度取一半 eg:8/2, 9/24.5,反转一半,到5时固定…

框架PasteForm实际开发案例,换个口味显示数据,支持echarts,只需要标记几个特性即可在管理端显示(2)

PasteForm框架的主要思想就是对Dto进行标记特性,然后管理端的页面就会以不一样的UI呈现 使用PasteForm框架开发,让你免去开发管理端的烦恼,你只需要专注于业务端和用户端! 在管理端中,如果说表格是基本的显示方式,那么图表chart就是一个锦上添花的体现! 如果一个项目拥…

Starrocks的Bitmap索引和Bloom filter索引以及全局字典

写这个的主要作用是梳理一下Starrocks的索引效率以及使用场景。 Starrocks Bitmap索引 原理&#xff1a; Bitmap 索引是一种使用 bitmap 的特殊数据库索引。bitmap 即为一个 bit 数组&#xff0c;一个 bit 的取值有两种&#xff1a;0 或 1。 每一个 bit 对应数据表中的一行&…