4、类加载器

2.4.1 什么是类加载器
类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术,类加载器只参与加载过程中的字节码获取并加载到内存这一部分。

在这里插入图片描述
类加载器会通过二进制流的方式获取到字节码文件的内容,接下来将获取到的数据交给Java虚拟机,虚拟机会在方法区和堆上生成对应的对象保存字节码信息。

2.4.2 类加载器的分类
类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。

  • 虚拟机底层实现:源代码位于Java虚拟机的源码中,实现语言与虚拟机底层语言一致,比如Hotspot使用C++。主要目的是保证Java程序运行中基础类被正确地加载,比如java.lang.String,Java虚拟机需要确保其可靠性。
  • JDK中默认提供或者自定义:JDK中默认提供了多种处理不同渠道的类加载器,程序员也可以自己根据需求定制,使用Java语言。所有Java中实现的类加载器都需要继承ClassLoader这个抽象类。

类加载器的设计JDK8和8之后的版本差别较大,首先来看JDK8及之前的版本,这些版本中默认的类加载器有如下几种:
在这里插入图片描述
类加载器的详细信息可以通过Arthas的classloader命令查看:
classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource
在这里插入图片描述

  • BootstrapClassLoader是启动类加载器,numberOfInstances是类加载器的数量只有1个,loadedCountTotal是加载类的数量1861个。
  • ExtClassLoader是扩展类加载器
  • AppClassLoader是应用程序类加载器

2.4.3 启动类加载器

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

运行如下代码:

/*** 启动程序类加载器案例*/
public class BootstrapClassLoaderDemo {public static void main(String[] args) throws IOException {ClassLoader classLoader = String.class.getClassLoader();System.out.println(classLoader);System.in.read();}
}

这段代码通过String类获取到它的类加载器并且打印,结果是null。这是因为启动类加载器在JDK8中是由C++语言来编写的,在Java代码中去获取既不适合也不安全,所以才返回null

在Arthas中可以通过sc -d 类名的方式查看加载这个类的类加载器详细的信息,比如:
在这里插入图片描述
通过上图可以看到,java.lang.String类的类加载器是空的,Hash值也是null。

用户扩展基础jar包
如果用户想扩展一些比较基础的jar包,让启动类加载器加载,有两种途径:

  • 放入jre/lib下进行扩展。不推荐,尽可能不要去更改JDK安装目录中的内容,会出现即时放进去由于文件名不匹配的问题也不会正常地被加载。
  • 使用参数进行扩展。推荐,使用-Xbootclasspath/a:jar包目录/jar包名 进行扩展,参数中的/a代表新增。

如下图,在IDEA配置中添加虚拟机参数,就可以加载D:/jvm/jar/classloader-test.jar这个jar包了。
在这里插入图片描述
2.4.4 扩展类加载器和应用程序类加载器

  • 扩展类加载器和应用程序类加载器都是JDK中提供的、使用Java编写的类加载器。
  • 它们的源码都位于sun.misc.Launcher中,是一个静态内部类。继承自URLClassLoader。具备通过目录或者指定jar包将字节码文件加载到内存中。

继承关系图如下:
在这里插入图片描述

  • ClassLoader类定义了具体的行为模式,简单来说就是先从本地或者网络获得字节码信息,然后调用虚拟机底层的方法创建方法区和堆上的对象。这样的好处就是让子类只需要去实现如何获取字节码信息这部分代码。
  • SecureClassLoader提供了证书机制,提升了安全性。
  • URLClassLoader提供了根据URL获取目录下或者指定jar包进行加载,获取字节码的数据。
  • 扩展类加载器和应用程序类加载器继承自URLClassLoader,获得了上述的三种能力。

扩展类加载器
扩展类加载器(Extension Class Loader)是JDK中提供的、使用Java编写的类加载器。默认加载Java安装目录/jre/lib/ext下的类文件。
如下代码会打印ScriptEnvironment类的类加载器。ScriptEnvironment是nashorn框架中用来运行javascript语言代码的环境类,他位于nashorn.jar包中被扩展类加载器加载

/*** 扩展类加载器*/
public class ExtClassLoaderDemo {public static void main(String[] args) throws IOException {ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();System.out.println(classLoader);}
}

打印结果如下:
在这里插入图片描述
通过扩展类加载器去加载用户jar包:

  • 放入/jre/lib/ext下进行扩展。不推荐,尽可能不要去更改JDK安装目录中的内容。
  • 使用参数进行扩展使用参数进行扩展。推荐,使用-Djava.ext.dirs=jar包目录 进行扩展,这种方式会覆盖掉原始目录,可以用;(windows):(macos/linux)追加上原始目录
    如下图中:
    在这里插入图片描述
    使用引号将整个地址包裹起来,这样路径中即便是有空格也不需要额外处理。路径中要包含原来ext文件夹,同时在最后加上扩展的路径。

应用程序加载器
应用程序类加载器会加载classpath下的类文件,默认加载的是项目中的类以及通过maven引入的第三方jar包中的类。
如下案例中,打印出Student和FileUtils的类加载器:

/*** 应用程序类加载器案例*/
public class AppClassLoaderDemo {public static void main(String[] args) throws IOException, InterruptedException {//当前项目中创建的Student类Student student = new Student();ClassLoader classLoader = Student.class.getClassLoader();System.out.println(classLoader);//maven依赖中包含的类ClassLoader classLoader1 = FileUtils.class.getClassLoader();System.out.println(classLoader1);Thread.sleep(1000);System.in.read();}
}

输出结果如下:
在这里插入图片描述
这两个类均由应用程序类加载器加载。

类加载器的加载路径可以通过classloader –c hash值 查看:
在这里插入图片描述

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

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

相关文章

【算法】数组-移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的…

CentOS、windows与Server_u服务器之间加密传输

一、适用场景: 1、保护数据传输:使用FTPS(FTP over SSL/TLS)可以加密FTP会话中的所有数据,从而防止数据在网络中被监听或篡改。 2、符合安全标准:许多行业标准要求数据传输必须是加密的。 3、保护用户凭证…

阿里云云服务器ECS端口多个端口号开通教程

阿里云云服务器ECS端口多个端口号开通教程 1、登录到ECS云服务器管理控制台 2、左侧栏找到【实例与镜像】>>【实例】,找到目标ECS实例,点击实例ID进入到实例详情页 3、切换到【安全组】页面,点击右侧【配置规则】,如下图&…

电力变电站自动化控制钡铼R40工业路由器4G全网通

随着电力行业的快速发展和电力系统的规模不断扩大,电力变电站自动化控制系统的建设和运行管理变得尤为重要。在这种背景下,钡铼R40工业路由器作为一款高性能、稳定可靠的通信设备,通过4G全网通技术,可以有效解决电力变电站自动化控…

WebXR实践——利用aframe框架浏览器展示全景图片

一、效果 话不多说&#xff0c;先上效果 二、代码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>360&deg; Image</title><meta name"description" content"360&deg; Imag…

第十二届蓝桥杯省赛CC++ 研究生组-路径

记录到每个结点的最短距离&#xff0c;以此为基础计算后续结点最优值 #include<iostream> #include<algorithm> using namespace std; typedef long long ll;ll gcd(int a, int b){if(!b) return a;return gcd(b, a % b); }int main(){ll dp[2022] {0};//dp[i]记…

uinapp开发-PHP语言-后端安装说明-适用于圈子-陪玩-交友-校园-团购-外卖-分销等多系统-APP小程序H5多端皆有!

后端安装说明 全新安装客户&#xff0c;按此安装调试步骤&#xff0c;请按顺序&#xff1a; ** 后台安装步骤及说明 ** 1、在服务器里安装宝塔。下载www.bt.cn。 宝塔安装完毕后&#xff0c;安装环境&#xff0c;Nginx或者Apache 请选择PHP7.3 数据库mysql5.6。 NGINX 1.22.1轻…

超越 GPT-4V 和 Gemini Pro!HyperGAI 发布最新多模态大模型 HPT,已开源

随着AI从有限数据迈向真实世界&#xff0c;极速增长的数据规模不仅赋予了模型令人惊喜的能力&#xff0c;也给多模态模型提供了更多的可能性。OpenAI在发布GPT-4V时就已经明确表示&#xff1a; 将额外模态&#xff08;如图像输入&#xff09;融入大语言模型&#xff08;LLMs&am…

1236 - 二分查找

代码 #include<bits/stdc.h> using namespace std; int a[1100000]; int main() {int n,x,l,r,p,mid,i;cin>>n;for(i1;i<n;i)cin>>a[i];cin>>x;l1;rn;p-1;while(l<r){mid(rl)/2;if(a[mid]x){pmid;break;}else if(x<a[mid]) rmid-1;else if(x…

3D轻量引擎HOOPS SDK:EDA应用程序高效开发利器

电子设计自动化&#xff08;EDA&#xff09;软件在现代工程实践中扮演着至关重要的角色。随着技术的不断进步和市场的竞争加剧&#xff0c;开发高效、可靠的EDA应用程序成为了行业内的一项迫切需求。在这一背景下&#xff0c;Tech Soft 3D的HOOPS SDK&#xff08;Software Deve…

两步法搞定:Python中的h5ad文件 转为R中的seurat对象

问题来源 AnnData对象&#xff08;Python中&#xff09;和Seurat对象&#xff08;R中&#xff09;分别是两个非常流行的单细胞RNA测序数据分析框架中的核心数据结构。 有很多工具可以完成python对象adata和R中seurat对象的转换&#xff0c;但是很多情况下&#xff0c;我们使用…

python家政服务系统flask-django-php-nodejs

相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低家政公司的运营人员成本&#xff0c;实现了家政服务的标准化、制度化、程序化的管理&#xff0c;有效地防止了家政服务的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、准确地…