学习总结与分享-ClassLoader类加载器与类加载机制

Java ClassNotFoundException 根因解析与类加载器排错指南 ClassNotFoundException 是 Java 运行时最常见却最易误判的异常,本质并非‘类不存在’,而是 JVM 类加载机制在类路径(Classpath)或模块路径(Module Path)中未能定位目标类。其底层原理根植于双亲委派模型——Bootstrap、Extension 和 Application 三层类加载器协同工作,严格遵循委托优先、隔离加载的原则。该异常的技术价值在于暴露环境配置缺陷而非代码错误,是诊断 Classpath 断链、模块可见性缺失、ClassLoader 上下文错位等 阅读详情

  在最初学习java时,我们都知道我们编写的java代码在执行前会被编写成class字节码文件,然后通过类加载器加载到jvm虚拟机中去执行,并开辟内存空间存储其中的字节码对象与初始化赋值。在平时编写代码时,我们其实也常常与类加载器打交道,比如反射调用,读取配置文件,动态代理等。。那么,类加载器又是如何工作的呢,其中又是怎么加载对象,给变量赋值的呢,这就是这次我要学习的问题了。
类加载的过程
类加载的生命周期分为加载、验证、准备、解析、初始化、使用、卸载,共七个步骤,其中加载、验证、准备、初始化、卸载这五个步骤的顺序是固定的,依次执行,而解析和使用的执行时间会视代码的编码情况来确认。
在这里插入图片描述
那么类在加载过程中都做了什么呢?
1.加载:
在加载阶段,虚拟机需要完成以下3件事情
(1) 通过一个类的全限定名来获取定义此类的二进制字节流
(2) 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
(3) 在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。
这里的加载和类的加载不是一个性质,这里是类加载器加载入jvm的第一步,通俗点讲就是类加载器根据类的全类名找到类在文件夹中的位置,将这个文件转换为二进制流,通过读取流,把对应的数据结构转换为jvm可运行的数据结构存储到jvm的方法区中,最后再在堆内存中生成一个字节码对象与这个方法区的数据结构对应。
这里我们再复习一下jvm虚拟机中的内存结构
在这里插入图片描述
2.验证:
确保类加载的正确性。一般情况由javac编译的class文件是不会有问题的,但是可能有人的class文件是自己通过其他方式编译出来的,这就很有可能不符合jvm的编译规则,这一步就是要过滤掉这部分不合法文件 
3.准备:
准备阶段是正式为类变量分配并设置类变量初始值的阶段,这些内存都将在方法区中进行分配(因为这里的变量都是类变量,实例变量在堆,类变量在方法区),在这里进行的是初始化赋值,就是将类变量的值赋为默认值,如int为0,boolean为false,引用为null等等。。下面是例子

	public static int value = 123;
	value在准备阶段过后的初始值为0而不是123,而把value赋值的putstatic指令将在初始化阶段才会被执行

4.解析:
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
符号引用是在class字节码文件最初未被jvm虚拟机执行的时候不知道实际的地址,所以由符号来代替,在解析后,再转换成虚拟机可以识别的直接引用。
5.初始化:
类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的java程序代码。在准备阶段变量已经付过一次系统要求的初始值,而在初始化阶段,则根据代码中编写的赋值去初始化类变量和其他资源
6.使用和卸载:
到这两个阶段的时候类的加载其实已经进入了尾声,内存中已经为类创建了对应的内存空间,为相应的变量赋值,并完成代码中的使用过程与使用过后的销毁。
到此,类的加载过程就已经解析完了,那么类中各种属性的加载时间与加载顺序又是什么样的呢?
类加载器的加载机制与加载顺序
类加载器在java中有三个内置的类加载器,他们负责加载不同的类。
(1) Bootstrap ClassLoader : 将存放于<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar 名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用
(2) Extension ClassLoader : 将<JAVA_HOME>\lib\ext目录下的,或者被java.ext.dirs系统变量所指定的路径中的所有类库加载。开发者可以直接使用扩展类加载器。
(3) Application ClassLoader : 负责加载用户类路径(ClassPath)上所指定的类库,开发者可直接使用。
类加载器使用的是双亲委派机制,来进行加载类。
双亲委派机制的原理:
如果一个类加载器接收到了类加载的请求,它首先把这个请求委托给他的父类加载器去完成,每个层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它在搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
好处:
java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类java.lang.Object,它存放在rt.jar中,无论哪个类加载器要加载这个类,最终都会委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果用户自己写了一个名为java.lang.Object的类,并放在程序的Classpath中,那系统中将会出现多个不同的Object类,java类型体系中最基础的行为也无法保证,应用程序也会变得一片混乱。
类在加载时的执行顺序,代码如下:

public class Test {
    private static Test test = new Test();
    private static final int FINALNUM = 123;
    private int num = 111;
    private static int staticNum = 99;
    {
        System.out.println("FINALNUM="+FINALNUM+",staticNum="+staticNum+",num="+num);
        System.out.println("=========1===========");
    }
    static {
        System.out.println("FINALNUM="+FINALNUM+",staticNum="+staticNum);
        System.out.println("**********2**********");
    }
    public Test() {
        System.out.println("FINALNUM="+FINALNUM+",staticNum="+staticNum+",num="+num);
        System.out.println("----------3----------");
    }
    public static void main(String[] args) {
        System.out.println("FINALNUM="+FINALNUM+",staticNum="+staticNum);
        System.out.println("##########4###########");
    }
}

执行结果:
在这里插入图片描述
这里就要说一下类加载器的加载顺序了,为什么13会在最上方,13的staticNum会为0,所有的FINALNUM都会有值呢
总结:
因为类在加载类变量的时候会在准备阶段先把int的值赋值为0默认值,并且类加载器在加载静态变量时,是按照代码的执行顺序来加载的,也就是说会先执行静态的实例化对象的过程,而在实例化对象时,构造代码块的执行又是最优先级的,所以出现了这样的执行顺序,而被final修饰的变量,在加载时会被类认为是不再改变的,所以会优先直接写入到内存中,所以始终会被读取到值

Android类加载机制全解析:从ClassLoader到热修复实战 类加载机制是JVM与Android运行时的基石,决定了类的查找顺序、加载时机与隔离边界。理解ClassLoader的继承体系与双亲委托原理,是排查ClassNotFoundException、NoClassDefFoundError等异常的关键,也是掌握热修复、插件化、MultiDex等高级技术的底层前提。Android中由BootClassLoader、PathClassLoader、DexClassLoader构成加载链路,而BaseDexClassLoader内部维护的Element数组则决定了类命中 阅读详情

相关推荐

为什么通过 类加载器 (ClassLoader) 可以访问静态文件,为什么要使用 this.getClass() 来获取类,并且该文件是如何被加载的?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,但经过精心筛选和整理,保证每一条解决方案都经过实战验证,真实可靠。

**My Coding Family** 1114

深入理解Java:类加载机制及反射

 说明:本文乃学习整理参考而来. 一、Java类加载机制 1.概述        Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。       虚拟机把描述类的数据从class文件加载到内存,并对...

weixin_34378922的博客 617

NVIDIA DGX Spark (Ubuntu 24.04) 部署Isaac Sim与Isaac Lab:二进制安装与ROS2集成实战

本文详细介绍了在NVIDIA DGX Spark工作站(Ubuntu 24.04系统)上,通过预编译二进制包稳定部署Isaac Sim与Isaac Lab的完整实战流程。文章重点剖析了二进制安装相较于源码编译和pip安装的优势,有效规避了CUDA、PyTorch等关键组件的版本冲突陷阱,并逐步指导完成环境配置、Isaac Lab集成、Conda环境管理以及ROS2 Jazzy的集成,最终构建出完整的机器人仿真与强化学习开发平台。

kite3的博客 396

java类加载器笔记

类加载 java

leede123456的博客 240

ROS中tf2_ros::Buffer.lookupTransform的正确使用姿势:从踩坑到填坑

本文深入解析了ROS中tf2_ros::Buffer.lookupTransform接口的正确使用方法,重点剖析了因tf2_ros::TransformListener生命周期管理不当导致的经典问题。文章提供了从理解Buffer与Listener共生关系、类成员设计黄金法则到参数详解与异常处理的完整避坑指南,并给出了构建健壮坐标变换工具类的实战方案,帮助开发者稳定实现机器人坐标系变换。

weixin_29253711的博客 134

大华事件检测智能服务器,大华股份:高速公路智能事件检测 解决方案

1方案背景随着我国基础设施建设的飞速发展,公路尤其是高速公路的总里程数年年攀升。交通运输部统计数据显示,截止2017年底全国公路总里程477.35万公里,其中高速公路13.65万公里,位居世界第一。高速公路的运营和管理作为全国交通管理的重要组成部分日益受到严峻挑战,交通拥堵和事故频发已成为高速公路上非常突出的问题。抛洒物、行人、车辆不规则行驶等事件是导致以上结果的重要原因。基于视频分析的高速公路智...

weixin_39523887的博客 1822

深入理解Java:类加载机制与反射

一、Java类加载机制 1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。 虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java

fengjie_123的专栏 677

SMPTE ST 2110 概论(一)

SMPTE ST 2110 概论(一)前言ST 2110与ST 2022-6ST 2110-10:基本结构与时序ST 2110-20:未压缩的视频流后续 前言 这是一份我在实习期间制作的,关于SMPTE ST 2110的简单介绍。 这篇文章主要以梳理总结 SMPTE ST 2110 的概念为主,关于具体的内容,比如IP数据报的格式、RTP时间戳的具体代码内容等等,大家可以查阅 SMPTE ST 2...

Cidd0422的博客 2万+

【潜意识Java】深挖Java的ClassLoader机制

除了上述三种默认的类加载器,我们还可以自定义类加载器。自定义类加载器可以满足一些特殊的需求,比如从网络、数据库等非传统文件系统中加载类,或者对类的字节码进行加密和解密等操作。要实现自定义类加载器,通常需要继承类,并重写findClass方法。System.out.println("对象的类加载器: " + obj.getClass().getClassLoader());在这个自定义类加载器的例子中,我们继承了。

潜意识Java的博客 866

手把手教你学Simulink实例:基于Simulink的超级电容器充放电仿真

超级电容器(Supercapacitor)是一种高容量电容器,具有快速充放电能力、长寿命和高功率密度等优点。它在能量存储系统、电动汽车、不间断电源(UPS)等领域有广泛应用。为了更好地理解和设计超级电容器的应用系统,通常需要进行详细的仿真分析。Simulink 提供了一个强大的仿真环境,可以用来设计、分析和验证超级电容器充放电系统的控制策略。本教程将详细介绍如何使用 Simulink 进行超级电容器充放电的仿真实例。通过本教程,我们详细介绍了如何使用 Simulink 进行超级电容器充放电的仿真实例。

MHD0815的博客 581

手把手教你学simulink(85.6)--非线性控制:滑模控制场景实例:基于Simulink建模仿真的滑模控制(Sliding Mode Control, SMC)在无人机自主飞行控制系统中的应用

首先,在MATLAB命令窗口中定义系统的参数和状态空间模型。matlab深色版本% 系统参数m = 1.5;% 无人机质量 (kg)g = 9.81;% 重力加速度 (m/s^2)% 惯性矩阵 (kg*m^2)% 初始条件pos0 = [0;0;0];% 初始位置 (m)vel0 = [0;0;0];% 初始速度 (m/s)0;0];% 初始姿态角 (rad)0;0];% 初始角速度 (rad/s)

MHD0815的博客 649

Java的类加载器

Java基础、Java类加载器学习记录

景川的博客 1155

【图像去噪】论文精读:FM2S: Self-Supervised Fluorescence Microscopy Denoising With Single Noisy Image

论文题目:FM2S: Self-Supervised Fluorescence Microscopy Denoising With Single Noisy Image —— FM2S:单噪声图像自监督荧光显微镜去噪arXiv 2024!显微图像去噪!通过可视化详细的细胞结构和生物过程,荧光显微镜具有显着先进的生物学研究。然而,由于难以精确建模固有噪声和获取干净图像进行训练,这种图像去噪任务往往面临挑战,这限制了大多数现有方法。在本文中,我们提出了一种有效的。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 408

深入理解ClassLoader工作机制:class文件,ClassLoader分类,四大类加载器,双亲委托 以及好处坏处

深入理解ClassLoader工作机制:class文件,ClassLoader分类,四大类加载器,双亲委托 以及好处坏处

qq120631157的博客 5115

CE电流法测试中的dBμV负值解析

传导发射(CE)电流法测试中出现的dBμV负值现象表明被测设备干扰电平低于1μV参考基准。这源于对数计算特性(小于1μV的电压转换后为负值)、设备优良的EMC设计(如滤波效果显著)及测试环境的影响(LISN隔离、屏蔽室低噪声)。负值虽不代表实际负电压,但反映干扰水平优于标准限值,为系统集成预留电磁裕度。工程应用中需结合设备灵敏度、环境背景噪声等因素综合分析,避免误判,这类数据可用于评估EMI设计冗余度。

硬核科技 298

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

[Java类加载器]Java中classLoader浅析.

[Java类加载器]Java中classLoader浅析. 本文为在公司内部TD上写的一篇小文, 主要讲解java中classLoader基础知识, 现在拿来这里分享一下. 一、问题 请在Eclipse中新建如下类,并运行它: 1 package java.lang; 2 3 public class Long { 4 public sta...

weixin_39941921的博客 124

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

day36-类加载器

基础加强包含了:反射,动态代理,类加载器,xml,注解,日志,单元测试等知识点其中最难的是反射和动态代理,其他知识点都非常简单由于B站P数限制,xml,注解等知识点,阿玮写了详细文档供大家学习。

2401_89213165的博客 699

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

YCBlogs Java 类加载系列:双亲委派机制详解与 ClassLoader 源码实战

本篇技术指南以 [双亲委派机制详读](https://link.gitcode.com/i/dfb5977598e868c27d1536454cdc0746) 为核心骨架,结合本仓库 [Java 类加载器介绍](https://link.gitcode.com/i/a54a70e334f5b07b8ee6f27c6c2ae384)、[类加载的详细过程](https://link.gitcode.c

gitblog_00390的博客 451

Java虚拟机探究第2讲: 类加载器ClassLoader

由于篇幅有限,这里就不一一罗列了,20道常见面试题(含答案)+21条MySQL性能调优经验小编已整理成Word文档或PDF文档还有更多面试复习笔记分享如下加入社区:https://bbs.youkuaiyun.com/forums/4304bb5a486d4c3ab8389e65ecb71ac0406579)]还有更多面试复习笔记分享如下[外链图片转存中…(img-HK4I4GQE-1725677406580)]

2401_86984580的博客 487

类加载器与双亲委派模型:JVM 类加载机制的基石

本篇文章基于 jvm9/jvm 知识库的 [类加载器专题文档](https://link.gitcode.com/i/ad360ebe704971cc3cae2cfcd6bda86e) 展开,围绕"类由谁加载、如何判定类的身份、三级加载器如何协作"这条主线,并结合本仓库 [类加载的过程](https://link.gitcode.com/i/c009f8f96f95780a4c2b31dfe299

gitblog_00089的博客 64

JVM(七):类加载器模型

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!Q笔记。

2401_84048225的博客 809

java基础:Java类加载器深度解析

Java类加载器作为语言体系的基础设施,在大厂的高并发、高可用的复杂系统中发挥着关键作用。解决依赖冲突等棘手问题实现灵活的热部署方案构建安全的模块化系统支持业务的多版本并行需求建议开发者在掌握基本原理的基础上,多研究Tomcat、OSGi等经典框架的类加载器实现,这将极大提升解决复杂类加载问题的能力。

weixin_43290370的博客 402

Java内存管理-掌握类加载器的核心源码和设计模式(六)

勿在流沙筑高台,出来混迟早要还的。 做一个积极的人 编码、改bug、提升自己 我有一个乐园,面向编程,春暖花开! 上一篇文章介绍了类加载器分类以及类加载器的双亲委派模型,让我们能够从整体上对类加载器有一个大致的认识,本文会深入到类加载器源码分析,了解类加载器ClassLoader中核心的源码,并且分析ClassLoader中的设计思想或者设计模式! 本文地图: 一、ClassLoader核...

阿飞云漫步 990

Java类加载器入门:从defineClass错误学起

当我们需要自定义类加载器时,正确的做法是继承ClassLoader类,然后重写findClass方法,而不是直接调用defineClass。在findClass方法中,我们可以读取字节码文件,然后调用父类的defineClass方法来完成类的定义。通过这次学习,我不仅解决了defineClass的错误,还对Java的类加载机制有了更深入的理解。类加载器分为三种:启动类加载器、扩展类加载器和应用类加载器。这个项目通过图形化界面展示了类加载的过程,并包含了可点击运行的示例代码。- 自定义类加载器的实现方式。

ThunderstormLynx23的博客 974

Android ClassLoader机制

今日科技快讯近日有消息称,因认为“即刻”APP未经其授权,擅自向公众提供2018年俄罗斯世界杯比赛画面动图点播服务,构成不正当竞争,央视国际网络有限公司将该APP运营商上...

郭霖 511

深入理解JVM类加载机制:双亲委派、自定义ClassLoader与线上排障实战

在Java运行时体系中,类加载机制是连接源码与JVM执行的桥梁。JVM通过三层类加载器与双亲委派模型,确保核心类不被篡改、同名类不会重复加载,从根源上保障了类型安全与稳定性。理解这一原理,不仅能解释ClassNotFoundException、NoClassDefFoundError等高频故障的差异,还能指导我们规避Metaspace区类泄漏、jar包版本冲突等隐蔽问题。更进一步,掌握自定义ClassLoader的编写方式,可实现加密类加载、热部署、版本隔离等工程能力;而线程上下文类加载器也为SPI机制提供

weixin_31102231的博客 126
上一篇: 学习总结与分享-浅析java的多态与策略模式
下一篇: 学习总结与分享-MySQL数据库索引底层原理入门浅析
VolcanoWec
博客等级 码龄8年 0粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值