【基础篇】四、类加载器ClassLoader

news2025/3/11 9:09:06

文章目录

  • 1、类加载器
  • 2、分类
  • 3、启动类加载器
  • 4、手动扩展启动类加载器
  • 5、扩展类加载器
  • 6、应用程序类加载器

1、类加载器

类加载器ClassLoader,是JVM提供给应用程序去获取类和接口的字节码数据的。

在这里插入图片描述

上面的类加载器对JVM进行了本地接口调用。本地接口即JNI,Java Native Interface,允许Java调用其他语言写的方法,如HostSpot类加载器调用JVM中用c++写的一些方法。

2、分类

两类:

  • Java代码中实现的:继承自抽象类ClassLoader
  • JVM底层源码实现的:用于加载程序运行时的基础类,如java.lang.String

在这里插入图片描述

使用Arthas来查看所有的类加载器:

//执行
classloader

除了上面提到的三种类加载器,DelegatingClassLoader是JDK底层用来提升反射效率的加载器

在这里插入图片描述

3、启动类加载器

启动类加载器(Bootstrap ClassLoader)是由Hotspot虚拟机提供的、使用C++编写的类加载器。 默认加载Java安装目录/jre/lib下的类文件,比如rt.jar(String、Integer、Date类都在这儿)、tools.jar、resources.jar

在这里插入图片描述

//尝试获取启动类的加载器
//相当于在Java程序(上层)中获取JVM(底层)的类加载器
public class BootstrapLoaderTest {

    public static void main(String[] args) throws IOException {
    
        ClassLoader classLoader = String.class.getClassLoader();
        
        System.out.println(classLoader);
    }
}
//返回null,从安全的角度考虑,这是合理的

在这里插入图片描述

继续用Arthas,sc指令查看某个类的详细信息

sc -d java.lang.String

发现这个基础类的加载器为空:

在这里插入图片描述

4、手动扩展启动类加载器

既然Java程序中获取不到启动类加载器,那如果后期我需要做扩展的jar包,如何让启动类加载器去加载我的jar呢:

  • 把自己的jar放入jre/lib下进行扩展:不推荐改JDK目录,放入也可能因为名称不会被正常加载
  • 使用参数扩展:-Xbootclasspath/a:jar包目录/jar包名,这里的a即add的含义

这里随便创建个模块,里面只有一个测试类MyLoad:

在这里插入图片描述

public class MyLoad {
    static {
        System.out.println("jar包中的Load类被加载了");
    }
}

mvn package打包后去另一个模块中添加JVM参数,

在这里插入图片描述

另一个模块中写个测试代码:

public class BootstrapLoaderTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName("com.plat.domain.MyLoad");
        System.out.println(clazz);
        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println(classLoader);
    }
}

运行,可以看到MyLoad类加载成功,且是被启动类加载器加载的:

在这里插入图片描述

以上的应用场景是:需要开发一些偏底层的类时,并需要用启动类加载器去加载它时,可考虑添加这个JVM参数,并把jar包拷贝到对应目录。如以镜像方式打包时,Dockerfile的cmd中可加ADD 操作,并添加JVM参数即可。

5、扩展类加载器

在这里插入图片描述

扩展类加载器负责加载那些通用,但不是很重要的类:Java安装目录下/jre/lib/ext下的类文件

在这里插入图片描述

比如上面的nashorn.jar,尝试获取这个jar中一个类ScriptEnvironment的类加载器:

public class LoaderTest {
    public static void main(String[] args) throws ClassNotFoundException {
    
        ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
        
        System.out.println(classLoader);
    }
}
//返回结果是扩展类加载器
sun.misc.Launcher$ExtClassLoader@1d44bcfa

如果以后的工作用写了一些通用,但不重要的类,可考虑让扩展类加载器去加载,扩展方式:

  • 放入/jre/lib/ext下进行扩展:不推荐去改JDK安装目录的内容
  • 使用参数:-Djava.ext.dirs=jar包目录
//-Djava.ext.dirs=jar包目录会覆盖原始的ext扩展目录
//正确用法为:
-Djava.ext.dirs=jar包目录;(windows的目录):(macos/linux的目录)

注意上面dirs路径中有空格时,运行报错,需要给dirs加上双引号,如:

-Djava.ext.dirs="C:\Program Files\jdk8\jre\lib\ext;D:\tmp\"

在这里插入图片描述

测试代码:

public class LoaderTest {
    public static void main(String[] args) throws ClassNotFoundException {
        //原有的
        ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
        System.out.println(classLoader);
        //让扩展类加载器去加载的jar
        Class<?> clazz = Class.forName("com.plat.domain.MyLoad");
        ClassLoader classLoader2 = clazz.getClassLoader();
        System.out.println(classLoader2);
    }
}

运行结果:

sun.misc.Launcher$ExtClassLoadera45ee12a7
sun.misc.Launcher$ExtClassLoader@45ee12a7

可以发现,JDK原来自己的ext目录下的类和我新加的jar包下的类,其类加载器都是扩展类加载器。保持了原扩展目录的同时,新加了自己的jar的类

6、应用程序类加载器

应用程序类加载器加载的是classPath下的类文件,包括项目中自己编写的类和接口的字节码文件,以及引入的第三方jar包中的类和接口的字节码文件

public class LoaderTest {
    public static void main(String[] args) throws ClassNotFoundException {
        //自己写的类
        ClassLoader classLoader1 = TestJvm.class.getClassLoader();
        System.out.println(classLoader1);
        //引入的jar的
        ClassLoader classLoader2 = FileUtil.class.getClassLoader();
        System.out.println(classLoader2);
    }
}

在这里插入图片描述

运行:

在这里插入图片描述

继续用Arthas工具,查看某个类加载器加载的路径全部打印出来

classloader –c hash值

在这里插入图片描述

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

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

相关文章

MySQL 中 blob 和 text 数据类型

应用场景 日志表中请求参数用的text&#xff0c;公告表中内容详情用的mediumblob。 1. blob 类型 blob(binary large object) 是一个可以存储二进制文件的容器&#xff0c;主要用于存储二进制大对象&#xff0c;例如可以存储图片&#xff0c;音视频等文件。按照可存储容量大小…

redis 从0到1完整学习 (七):ZipList 数据结构

文章目录 1. 引言2. redis 源码下载3. zipList 数据结构3.1 整体3.2 entry 数据结构分析3.3 连锁更新 4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&am…

Python(五)—— 闭包装饰器

13. 闭包 13.1 闭包的案例 给大家提个需求&#xff0c;然后用函数去实现&#xff1a;完成一个计算不断增加的系列值的平均值的需求 例如&#xff1a;整个历史中的某个商品的平均收盘价。就是从这个商品一出现开始&#xff0c;每天记录当天价格&#xff0c;然后计算他的平均值…

SpringBoot源码搭建

文章目录 源码下载搭建项目构建学习博客 源码下载 需要环境 &#xff1a; JDK 1.8Maven 3.5Spring Boot 1.x.x: Gradle 版本建议为2.9或更高版本。Spring Boot 2.x.x: Gradle 版本建议为4.x.x或更高版本。 GitHub 从v2.3.x开始&#xff0c;SpringBoot开始强制用Gradle构建项…

深度解析:CRM、ERP之间的关联和区别以及双系统的联系与集成(附系统架构图)

目录 一、系统简介 1.1 CRM是什么 1.2 ERP是什么 二、发展阶段 2.1 CRM发展阶段 2.2 ERP发展阶段 三、系统架构 3.1 CRM系统架构 3.2 ERP系统架构 四、CRM与ERP的区别 4.1 目标不同 4.2 不同阶段的发展中不同的适用性 4.2.1 刚起步的小公司 4.2.2 对于更大、更成…

数字电子技术 一天速成

文章目录 一、数制与编码1. 数制转换2. BCD编码 二、逻辑代数1. 常见逻辑运算及逻辑门 三、化简逻辑表达式1. 卡诺图 求 表达式2. 表达式 画 卡诺图3. 卡诺图 化简 表达式4. 公式法 化简 表达式 ⭐⭐5. 表达式 求 反函数6. 卡诺图 求 反函数 四、组合逻辑电路的分析和设计1. 逻…

Gin框架之使用 go-ini 加载.ini 配置文件

首先,联想一个问题,我们在部署服务时,通常为了方便,对于需要迭代更新的代码进行修改,但是比对shell,可以搞一个变量将需要修改的,以及修改起来变动处多的,写在变量内,到时候如果需要变更,可以直接变更变量即可; 那么,golang有没有什么方式可以将需要变的东西保存起…

Hexo 部署 Github Pages, Github Actions自动部署

想整个静态的博客部署在github pages 历经两天的折磨终于是摸索成功了&#xff0c;官网的文档太简陋了&#xff0c;很多东西没说清楚。 欢迎大家访问我的博客&#xff01; Canyue 最终实现的效果&#xff0c;一个项目仓库&#xff0c;main 分支存放源代码&#xff0c;gh-page…

H266/VVC帧间预测编码技术概述

帧间预测编码简述 帧间预测利用视频时间域的相关性&#xff0c;使用邻近已编码图像像素值预测当前图像的像素值&#xff0c;能有效去除视频时域冗余。 目前主要的视频编码标准中&#xff0c;帧间预测都采用基于块的运动补偿技术&#xff0c;不同的编码标准有不同的分块方式。 …

Spring企业开发核心框架

文章目录 Spring企业开发核心框架一、框架前言1. 总体技术体系2. 框架概念和理解 二、Spring Framework简介1. Spring 和 SpringFramework2. SpringFramework主要功能模块3. SpringFramework 主要优势 三、Spring IoC 容器概念1. 组件和组件管理概念2. Spring IoC容器和容器实现…

C# LINQ

一、前言 学习心得&#xff1a;C# 入门经典第8版书中的第22章《LINQ》 二、LINQ to XML 我们可以通过LINQ to XML来创造xml文件 如下示例&#xff0c;我们用LINQ to XML来创造。 <Books><CSharp Time"2019"><book>C# 入门经典</book><…

上海亚商投顾:沪指冲高回落 游戏股午后集体重挫

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数12月22日冲高回落&#xff0c;黄白二线分化严重。游戏股午后大跌&#xff0c;盛天网络、游族网络、巨…

【JAVA】黑马MybatisPlus 学习笔记【终】【插件功能】

4.插件功能 MybatisPlus提供了很多的插件功能&#xff0c;进一步拓展其功能。目前已有的插件有&#xff1a; PaginationInnerInterceptor&#xff1a;自动分页TenantLineInnerInterceptor&#xff1a;多租户DynamicTableNameInnerInterceptor&#xff1a;动态表名OptimisticL…

bootstrap:bootstrapValidator校验数据是否可用(验证账户名是否重复)

目录 1、html内容 2、bootstrap的校验 3、控制层代码&#xff1a; 4、业务层核心代码 5、效果 1、html内容 <form id"jangleEditForm" name"jangleEditForm" class"formJ" ><div class"form-group" ><label for&q…

10个练习Web渗透测试的最佳网站

黑客的最高境界——社会工程学&#xff01;社会工程在网络安全领域充当了关键角色&#xff01;黑客技术如何操纵信息安全&#xff1f;社会工程攻击的多种形式&#xff0c;包括网络钓鱼、电子邮件欺诈、诱饵场景&#xff1b;如何应对黑客利用未提出的问题的策略。防范黑客社会工…

二叉树OJ题——3.翻转二叉树

226. 翻转二叉树 - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 翻转每一棵树的左右子树根节点 */void swap (struct TreeNode**x,struct TreeNode**y) {struct TreeNode*num0;num*x;*x*y;*ynum; }struct TreeNode* invertTree(struct TreeNode* root) { i…

【广州华锐互动】VR科技科普展厅平台:快速、便捷地创建出属于自己的虚拟展馆

随着科技的不断进步&#xff0c;虚拟现实(VR)技术已经在许多领域取得了显著的成果。尤其是在展馆设计领域&#xff0c;VR科技科普展厅平台已经实现了许多令人瞩目的新突破。 VR科技科普展厅平台是广州华锐互动专门为企业和机构提供虚拟展馆设计和制作的在线平台。通过这个平台&…

二分查找——OJ题(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、点名1、题目讲解2、算法原理3、代码实现 二、搜索旋转排序数组中的最⼩值1、题目讲解2、算…

LabVIEW在齿轮箱故障诊断中的应用

LabVIEW在齿轮箱故障诊断中的应用 在现代机械工业中&#xff0c;齿轮箱作为重要的传动设备&#xff0c;其性能稳定性对整体机械系统的运行至关重要。故障的及时诊断和处理不仅保障了设备的稳定运行&#xff0c;还减少了维护成本。利用LabVIEW强大数据处理和仿真能力&#xff0…

在k8s中将gitlab-runner的运行pod调度到指定节点

本篇和前面的 基于helm的方式在k8s集群中部署gitlab 具有很强的关联性&#xff0c;因此如果有不明白的地方可以查看往期分享&#xff1a; 基于helm的方式在k8s集群中部署gitlab - 部署基于helm的方式在k8s集群中部署gitlab - 备份恢复基于helm的方式在k8s集群中部署gitlab - 升…