jvm基础三——类加载器

类加载器

在Java中,类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将类文件(.class文件)加载到JVM中,使得程序能够使用这些类。类加载器在Java中具有重要的作用,它的主要任务包括:

  1. 加载(Loading):找到并加载类文件的字节码数据。类加载器根据类的全限定名(Fully Qualified Name)来查找并读取对应的类文件。

  2. 链接(Linking):链接包括验证、准备和解析这三个步骤。

    • 验证(Verification):确保类文件的字节码符合JVM规范,并且安全地加载到JVM中。
    • 准备(Preparation):为类的静态变量分配内存,并设置默认初始值。
    • 解析(Resolution):将符号引用转换为直接引用。
  3. 初始化(Initialization):对类进行初始化,包括执行静态代码块和初始化静态变量等。

Java的类加载器采用了双亲委派模型(Parent Delegation Model)。根据这个模型,当需要加载一个类时,类加载器首先会委派给父类加载器加载,只有在父类加载器无法加载该类时,才会尝试自己加载。这种层次化的类加载器体系保证了类的统一性和安全性,同时也避免了类的重复加载。

Java中的类加载器可以分为以下几种类型:

  1. Bootstrap Class Loader(引导类加载器):是JVM的一部分,它负责加载JVM自身需要的类,包括java.lang包中的类。它是用本地代码(Native Code)实现的,无法直接在Java中获取对其的引用。

  2. Extension Class Loader(扩展类加载器):负责加载Java的扩展库,位于JRE的lib/ext目录下的类。它是由sun.misc.Launcher$ExtClassLoader类实现的,是Bootstrap Class Loader的子类。

  3. Application Class Loader(应用程序类加载器):也叫系统类加载器,负责加载应用程序中的类。它是由sun.misc.Launcher$AppClassLoader类实现的,是Extension Class Loader的子类。

  4. 自定义类加载器:Java允许用户自定义类加载器,继承自java.lang.ClassLoader类,实现自定义的加载逻辑。通过自定义类加载器,可以实现一些特殊的类加载需求,比如从网络、数据库或其他非标准位置加载类。

Java的类加载器机制为Java程序提供了灵活性和安全性,可以根据不同的需求扩展或自定义类加载器,实现各种复杂的类加载逻辑

 

类加载器的双亲委派机制 

Java中的类加载器采用了双亲委派机制(Parent Delegation Model),这是一种类加载器的工作原则,用于保证类加载的统一性和安全性。该机制基于一个简单的原则:除非父类加载器无法加载该类,否则由父类加载器加载。

下面是双亲委派机制的工作流程:

  1. 当一个类加载器收到加载类的请求时,它首先不会自己尝试去加载这个类,而是把请求委托给父类加载器去完成。

  2. 每个类加载器都会把加载请求向上委托给父类加载器,直到达到顶层的引导类加载器(Bootstrap Class Loader)。

  3. 如果父类加载器可以加载这个类,就成功返回;如果父类加载器无法加载,子类加载器才会尝试自己去加载这个类。

这种机制的优势在于确保了Java核心库的一致性:无论哪个类加载器加载一个类,最终被加载的类都是相同的。这样可以避免在不同的类加载器下出现同名类的冲突问题。

双亲委派机制还提高了安全性。因为在这种机制下,Java类的加载都是从根加载器开始的,根加载器只加载标准的核心Java类库,不会加载应用程序的类。这样可以防止应用程序通过替换核心Java类库中的类来破坏JVM的稳定性和安全性。

总的来说,双亲委派机制保证了类加载的一致性、安全性和稳定性,是Java类加载机制的核心之一。

打破

尽管双亲委派机制在大多数情况下都是非常有用的,但在某些特殊情况下,可能需要打破双亲委派机制。打破双亲委派机制通常是为了实现一些特殊的类加载需求,比如热部署、动态更新等。

在Java中,要打破双亲委派机制,一般需要自定义类加载器,并重写其加载类的方法。下面是一种可能的方法:

  1. 自定义类加载器:继承自 ClassLoader 类,并重写 loadClass() 方法

  2. loadClass() 方法中,根据需要的加载策略,决定是否调用父类加载器的 loadClass() 方法。

  3. 如果需要打破双亲委派机制,可以在自定义类加载器的 loadClass() 方法中直接加载指定类,而不是委托给父类加载器。

下面是一个简单的示例代码,演示如何打破双亲委派机制:

public class MyClassLoader extends ClassLoader {@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {if (name.startsWith("com.example")) {// 对于指定的类,直接由自定义类加载器加载return findClass(name);}// 其他类委托给父类加载器加载return super.loadClass(name);}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {// 实现自定义的类加载逻辑,比如从文件或网络加载类的字节码数据// 这里只是一个简单示例,实际应用中需要根据具体需求实现byte[] classData = getClassData(name);if (classData == null) {throw new ClassNotFoundException(name);}return defineClass(name, classData, 0, classData.length);}// 实现获取类字节码数据的方法,这里只是一个简单示例,实际应用中需要根据具体需求实现private byte[] getClassData(String name) {// 从指定的位置获取类字节码数据// 这里可以是文件、网络等来源return null;}
}

在上面的示例中,自定义了一个 MyClassLoader 类继承自 ClassLoader,重写了 loadClass() 方法和 findClass() 方法。在 loadClass() 方法中,指定了对于以 "com.example" 开头的类,直接由自定义类加载器加载,而对于其他类,委托给父类加载器加载。在 findClass() 方法中,实现了加载类的具体逻辑,可以从指定的位置获取类的字节码数据并定义类。

需要注意的是,打破双亲委派机制可能会导致类加载冲突和安全问题,因此应谨慎使用,并确保了解其潜在的影响。

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSError: Can‘t load tokenizer for ‘bert-base-chinese‘

文章目录 OSError: Cant load tokenizer for bert-base-chinese1.问题描述2.解决办法 OSError: Can’t load tokenizer for ‘bert-base-chinese’ 1.问题描述 使用from_pretrained()函数从预训练的权重中加载模型时报错&#xff1a; OSError: Can’t load tokenizer for ‘…

达梦数据库 优化

谁进行优化&#xff1f;优化什么&#xff1f; 优化不能仅从数据库方面考虑&#xff0c;比如&#xff0c;在存储达到数据库极限、应用涉及人员设计的代码稀巴烂的情况下&#xff0c;进行调优就是杯水车薪的效果。 涉及到优化人员&#xff1a; 数据库管理员应用程序架构师应用…

数据结构|排序总结(1)|直接插入排序

排序分类 插入排序&#xff1a;直接插入排序&#xff0c;希尔排序 选择排序&#xff1a;选择排序&#xff0c;堆排序 交换排序&#xff1a;冒泡排序&#xff0c;快速排序 归并排序 插入排序 直接插入排序 相当于摸牌&#xff0c;例如我们现在手上有{2&#xff0c;4&#xff0…

MySql并发事务问题

事务 事务概念&#xff1a; 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务的特性&#xff1a;ACID&#xff1a; 小…

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象&#xff1f;2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…

Unity性能优化篇(十四) 其他优化细节以及UPR优化分析器

代码优化&#xff1a; 1. 使用AssetBundle作为资源加载方案。 而且经常一起使用的资源可以打在同一个AssetBundle包中。尽量避免同一个资源被打包进多个AB包中。压缩方式尽量使用LZ4&#xff0c;少用或不要用LZMA的压缩方式。如果确定后续开发不会升级Unity版本&#xff0c;则可…

【Java EE】初识Spring Web MVC

文章目录 &#x1f334;什么是Spring Web MVC&#xff1f;&#x1f338;什么是Servlet呢? &#x1f332;MVC 定义&#x1f338;再理解Spring MVC &#x1f333;如何学习Spring MVC呢&#xff1f;⭕总结 &#x1f334;什么是Spring Web MVC&#xff1f; Spring Web MVC 是基于…

《捕鱼_ue4-5输出带技能的透明通道素材到AE步骤》

《捕鱼_ue4-5输出带技能的透明通道素材到AE步骤》 2022-05-17 11:06 先看下带透明的特效素材效果1、首先在项目设置里搜索alpha&#xff0c;在后期处理标签设置最后一项allow through tonemapper2、在插件管理器中&#xff0c;搜索movie render &#xff0c;加载movie render q…

图论模板详解

目录 Floyd算法 例题&#xff1a;蓝桥公园 Dijkstra算法 例题&#xff1a;蓝桥王国 SPFA算法 例题&#xff1a;随机数据下的最短路问题 总结 最小生成树MST Prim算法 Kruskal算法 例题&#xff1a;聪明的猴子 Floyd算法 最简单的最短路径算法&#xff0c;使用邻接…

win10上一个详细的Django开发入门例子

1.Django概述 Django是一个开放源代码的Web应用框架&#xff0c;由Python写成。采用了MTV的框架模式&#xff0c;即模型M&#xff0c;视图V和模版T。 Django 框架的核心组件有&#xff1a; 用于创建模型的对象关系映射&#xff1b; 为最终用户设计较好的管理界面&#xff1b…

数学矩阵GCD和lCM(详解)

矩阵乘法 知阵乘法是《线性代数》中的基础内容&#xff0c;但在考察数学的算法题中也会出现。 本节我们学习基础的矩阵乘法规则。 每个矩阵会有一个行数和一个列数&#xff0c;只有当相乘的两个矩阵的左矩阵的列数等于右矩阵的行数 时&#xff0c;才能相乘&#xff0c;否则不允…

Rust---复合数据类型之枚举、数组

目录 枚举的使用Option 枚举数组的使用输出结果 枚举&#xff08;Enum&#xff09;&#xff1a;表示一个类型可以有多个不同的取值。枚举类型可以包含不同的变体&#xff08;variants&#xff09;&#xff0c;每个变体可以有不同的数据类型。 枚举的使用 enum Direction {Up,…

LeetCode-131. 分割回文串【字符串 动态规划 回溯】

LeetCode-131. 分割回文串【字符串 动态规划 回溯】 题目描述&#xff1a;解题思路一&#xff1a;回溯&#xff0c; 回溯三部曲解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个…

八股面试速成—Java语法部分

暑期实习面试在即&#xff0c;这几天八股和算法轮扁我>_ 八股部分打算先找学习视屏跟着画下思维导图&#xff0c;然后看详细的面试知识点&#xff0c;最后刷题 其中导图包含的是常考的题&#xff0c;按照思维导图形式整理&#xff0c;会在复盘后更新 细节研究侧重补全&a…

牛客NC181 单词拆分(一)【中等 动态规划,前缀树 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/c0d32c1ce5744472a01b2351a2c2767f 思路 前缀树动态规划参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规…

Docker、Kubernetes之间的区别

比较容器化工具&#xff1a;了解 Docker、Kubernetes 在应用程序部署和管理方面的差异。 基本概述 Docker 是一个流行的容器化平台&#xff0c;允许开发人员在容器中创建、部署和运行应用程序。 Docker 提供了一组工具和 API&#xff0c;使开发人员能够构建和管理容器化应用程…

C++输出格式控制

setprecision(n)可控制输出流显示浮点数的数字个数。C默认的流输出数值有效位是6&#xff0c;所以不管数据是多少&#xff0c;都只输出六位。如果setprecision(n)与setiosflags(ios::fixed)或者setiosflags(ios_base::fixed)合用&#xff0c;可以控制小数点右边的数字个数。set…

数据结构面试题报错调试方法记录

栈和队列报错调试 1.用栈实现队列 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 此题解题思路如下&#xff1a; 先将数据放在pushst栈里面&#xff0c;popst栈为空再把pushst栈里面的数据放进popst栈里面去&#xff0c;不为空则不执行。不为空时候直接拿取栈…

机器学习模型——关联规则

目录 关联规则 - 基本概念 关联规则的挖掘步骤: Apriori算法 Apriori算法简介&#xff1a; Apriori算法举例&#xff1a; Apriori算法优缺点&#xff1a; Apriori算法应用 FP-growth算法&#xff1a; FP-growth算法简介&#xff1a; FP-growth的数据结构&#xff1a; …

Mysql的基本命令

1 服务相关命令 命令描述systemctl status mysql查看MySQL服务的状态systemctl stop mysql停止MySQL服务systemctl start mysql启动MySQL服务systemctl restart mysql重启MySQL服务ps -ef | grep mysql查看mysql的进程mysql -uroot -hlocalhost -p123456登录MySQLhelp显示MySQ…