类加载器介绍

目录

什么是类加载器?

 类加载器的层次结构

类加载器的工作原理

双亲委派模型:

如何获取类加载器

获取类加载器的方法

url----输出绝对地址

InputStream--获取资源文件的输入流

使用 URL 和 InputStream

 示例代码

如何从URL获取 InputStream 并读取数据: 

注意事项


什么是类加载器?

类加载器(Class Loader)是 Java 虚拟机(JVM)的一部分,负责将类文件(.class 文件)加载到 JVM 中。类加载器在 Java 应用程序的启动和运行过程中起着至关重要的作用。

 类加载器的层次结构

Java 类加载器采用层次结构,主要包括以下几种:
(1)Bootstrap Class Loader(引导类加载器)
负责加载 Java 核心库(如 rt.jar),位于 JAVA_HOME/jre/lib 目录下。
由原生代码实现,不是 Java 类,因此无法直接访问。
(2)Extension Class Loader(扩展类加载器)
负责加载 Java 的扩展库,位于 JAVA_HOME/jre/lib/ext 目录下。
实现为 sun.misc.Launcher$ExtClassLoader。
(3)Application Class Loader(应用类加载器)
也称为系统类加载器,负责加载应用程序类路径(CLASSPATH)下的类。
实现为 sun.misc.Launcher$AppClassLoader。
(4)Custom Class Loader(自定义类加载器)
开发者可以创建自定义类加载器,用于加载特定目录或网络路径下的类文件。
继承自 java.lang.ClassLoader 类。

类加载器的工作原理

双亲委派模型:

(1)当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。
(2)每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器。
(3)只有当父类加载器无法加载该类时,子类加载器才会尝试自己去加载。

如何获取类加载器

获取类加载器的方法


在Java中,有多种方式可以获取类加载器。以下是一些常见的方法:
获取当前类的类加载器 :

   ClassLoader classLoader = MyClass.class.getClassLoader();

获取当前线程上下文类加载器:

   ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

获取系统类加载器(应用程序类加载器):

   ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

获取启动类加载器
启动类加载器是用C++实现的,不能直接获取其引用。但是可以通过以下方式间接判断一个类是否由启动类加载器加载:

   ClassLoader bootstrapClassLoader = String.class.getClassLoader();if (bootstrapClassLoader == null) {System.out.println("This class is loaded by the Bootstrap Class Loader.");}

示例代码
以下是一些示例代码,展示了如何获取不同类型的类加载器:

public class ClassLoaderExample {public static void main(String[] args) {// 获取当前类的类加载器ClassLoader currentClassLoader = ClassLoaderExample.class.getClassLoader();System.out.println("Current Class Loader: " + currentClassLoader);// 获取当前线程上下文类加载器ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();System.out.println("Context Class Loader: " + contextClassLoader);// 获取系统类加载器(应用程序类加载器)ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println("System Class Loader: " + systemClassLoader);// 获取启动类加载器ClassLoader bootstrapClassLoader = String.class.getClassLoader();if (bootstrapClassLoader == null) {System.out.println("String class is loaded by the Bootstrap Class Loader.");} else {System.out.println("String class loader: " + bootstrapClassLoader);}}
}

输出示例
假设上述代码在一个标准的Java应用程序中运行,输出可能如下:

Current Class Loader: sun.misc.Launcher$AppClassLoader@18b4aac2
Context Class Loader: sun.misc.Launcher$AppClassLoader@18b4aac2
System Class Loader: sun.misc.Launcher$AppClassLoader@18b4aac2
String class is loaded by the Bootstrap Class Loader.

解释
当前类的类加载器:ClassLoaderExample.class.getClassLoader() 返回加载 ClassLoaderExample 类的类加载器,通常是应用程序类加载器。
当前线程上下文类加载器:Thread.currentThread().getContextClassLoader() 返回当前线程的上下文类加载器,通常也是应用程序类加载器。
系统类加载器:ClassLoader.getSystemClassLoader() 返回系统类加载器,即应用程序类加载器。
启动类加载器:String.class.getClassLoader() 返回 null,表示 String 类是由启动类加载器加载的。

url----输出绝对地址

直接获取字节码的根路径

ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//URL 统一资源定位符, 其实里面维护了一个绝对路径
URL url = systemClassLoader.getResource("a.txt");
String path = url.getPath();
System.out.println(path);     

InputStream--获取资源文件的输入流

 可以直接读取字节码下面的资源!

//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//找到根目录下的a.txt文档(当文件被加载后,只会保留src下面的文件),获取资源文件的输入流
InputStream in = systemClassLoader.getResourceAsStream("a.txt");
Properties properties = new Properties();
//将输入流对象传入
properties.load(in);

使用 URL 和 InputStream

在Java中,可以通过 URL 对象和 InputStream 来读取网络资源的内容。以下是一些常见的步骤和示例代码,展示如何从URL获取 InputStream 并读取数据。
步骤:

  1. 创建 URL 对象:使用 URL 类的构造函数或 URL 类的 new URL(String spec) 方法创建 URL 对象。
  2. 打开连接:调用 URL 对象的 openConnection() 方法获取 URLConnection 对象。
  3. 获取 InputStream:调用 URLConnection 对象的 getInputStream() 方法获取 InputStream。
  4. 读取数据:使用 InputStream 读取数据,通常会使用 BufferedReader 或其他流处理工具来简化操作。
  5. 关闭资源:读取完成后,关闭 InputStream 以释放资源。

 示例代码

如何从URL获取 InputStream 并读取数据: 


以下是一个完整的示例代码,展示了如何从URL获取 InputStream 并读取数据: 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;public class URLInputStreamExample {public static void main(String[] args) {String urlString = "https://example.com";try {// 创建 URL 对象URL url = new URL(urlString);// 打开连接URLConnection connection = url.openConnection();// 获取 InputStreamtry (InputStream inputStream = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {// 读取数据String line;while ((line = reader.readLine()) != null) {System.out.println(line);}}} catch (IOException e) {e.printStackTrace();}}
}

注意事项

异常处理:在实际应用中,建议对 IOException 进行更详细的处理,例如记录日志或重试机制。
超时设置:可以通过 URLConnection 对象的 setConnectTimeout(int timeout) 和 setReadTimeout(int timeout) 方法设置连接和读取的超时时间,防止长时间阻塞。
字符编码:如果URL资源的编码不是默认的UTF-8,可以在 InputStreamReader 构造函数中指定编码,例如 new InputStreamReader(inputStream, "ISO-8859-1")。

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

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

相关文章

2024下半年软考机考模拟系统已开放!小伙伴们速速练起来

千呼万唤使出来,软考机考的模拟练习系统已于10月23号正式开放! 今年报名计算机技术与软件专业技术资格(水平)考试(软考)的小伙伴们千万不要忘记哦! 01、开放时间 据中国计算机技术职业资格网发…

基于AI识别数据的Vue.js图像框选标注

在数字化时代,图像识别技术的应用越来越广泛,尤其是在车牌识别、人脸识别等领域。本文将介绍如何使用Vue.js框架和JavaScript创建一个交互式组件,该组件不仅允许用户在图片上绘制多个区域,加载文字,还提供了清空功能。…

外包干了2个月,技术明显退步

回望过去,我是一名普通的本科生,于2019年通过校招有幸加入了南京某知名软件公司。那时的我,满怀着对未来的憧憬和热情,投入到了功能测试的岗位中。日复一日,年复一年,转眼间,我已经在这个岗位上…

常用shell指令

这些指令通常在adb shell环境中使用,或者通过其他方式(如SSH)直接在设备的shell中使用。 文件操作命令 ls:列出目录的内容 ls /sdcard cd:改变目录 cd /sdcard/Download pwd:打印当前工作目录 pwd cat&…

CV2通过一组轮廓点扣取图片

代码如下: import cv2 import numpy as np# 读取原始图像 original_image cv2.imread(img.png)# 定义一组轮廓点(这里只是示例,你需要根据实际情况替换) points np.array([[50, 100], [100, 200], [200, 150], [200, 50], [160…

负载均衡服务器攻击怎么解决最有效?

负载均衡服务器攻击怎么解决最有效?常见的有效解决方法包括:使用SYNCookie机制、限制ICMP包速率、基于源IP的连接速率限制、检测并丢弃异常IP包、配置访问控制列表(ACL)、设置虚拟服务器/服务器连接数量限制、设置HTTP并发请求限制…

【景观生态学实验】实验二 景观类型分类

实验目的 1.掌握ArcGIS软件的基本操作:通过课堂理论学习与实验课的实际动手操作,学习并熟练掌握如何利用ArcGIS软件对遥感影像进行一些较为基础的数据处理与分析工作,具体包括波段合成、图像镶嵌、图像裁剪与图像分类等; 2.熟悉…

基于STM32设计的养殖场环境监测系统(华为云IOT)

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】需求总结 1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发 二、部署华为云物联网平台2.1 物联网平台介绍2.2 开通物联网服务2.3 创建产品&#x…

微信小程序-获取头像和昵称

一.获取头像 1.将button组件open-type的值设置为chooseAvatar 2.通过bindchooseavatar事件回调获取到头像信息的临时路径 wxml文件代码&#xff1a; <view> <button class"btn" open-type"chooseAvatar" bindchooseavatar"chooseavatar&qu…

生成式人工智能

这个接龙的生成就是概率式的&#xff0c;下一个接龙的字是有概率的 本身就是在做文字接龙的游戏&#xff0c;不会搜索网上的资料

Zig语言通用代码生成器:逻辑,冒烟测试版发布

#1024程序员节 | 征文# Zig语言通用代码生成器&#xff1a;逻辑&#xff0c;冒烟测试版发布 Zig语言是一种新的系统编程语言&#xff0c;其生态位类同与C&#xff0c;是前一段时间大热的rust语言的竞品。它某种意义上的确非常像rust&#xff0c;尤其是在开发过程中无穷无尽抛错…

【哈工大_操作系统理论】L282930 生磁盘的使用从生磁盘到文件文件使用磁盘的实现

L4.3 生磁盘的使用 1、认识磁盘 选择磁道旋转扇区数据读写 哪一个柱面 C哪一个磁头 H哪一个扇区 S 2、第一层抽象&#xff1a;盘块号block 发送盘块号block&#xff0c;磁盘驱动根据 block 计算出 cyl、head、sec&#xff08;CHS&#xff09; 磁盘访问时间主要是寻道时间…

精准布局:探索CSS中的盒子固定定位的魅力

一、概念 固定定位使元素相对于浏览器窗口进行定位&#xff0c;无论网页如何滚动&#xff0c;固定定位的元素也会保持在相同的位置&#xff0c;设置固定定位的元素脱离文档流。 二、语法结构 <style>选择器{/* fixed 固定定位 */position: fixed;}</style> 与绝…

LeetCode练习-删除链表的第n个结节

大家好&#xff0c;依旧是你们的萧萧啊。 今天我们来练习一个经典的链表问题&#xff1a;删除链表的第n个节点。在这篇文章中&#xff0c;我们将深入分析这个问题&#xff0c;并给出一个有效的解决方案。 问题描述 给定一个链表&#xff0c;要求删除链表的倒数第n个节点&…

WRB Hidden Gap,WRB隐藏缺口,MetaTrader 免费公式!(指标教程)

WRB Hidden Gap MetaTrader 指标用于检测和标记宽范围的柱体&#xff08;非常长的柱体&#xff09;或宽范围的烛身&#xff08;具有非常长实体的阴阳烛&#xff09;。此指标可以识别WRB中的隐藏跳空&#xff0c;并区分显示已填补和未填补的隐藏跳空&#xff0c;方便用户一眼识别…

GEE数据集:1984-2022 年间加拿大 6.5 亿公顷森林生态系统的年度优势树种(也称主要树种)地图

目录 简介 数据集说明 空间信息 变量 代码 代码链接 下载链接 引用 许可 网址推荐 0代码在线构建地图应用 机器学习 简介 加拿大长期树种&#xff08;1984-2022 年&#xff09;∥在该数据集中&#xff0c;我们利用空间分辨率为 30 米的 Landsat 时间序列图像&…

etl-查询错误log日志和oracle删除数据表空间

查看weblogic日志的目录 建立连接ssh root192.168.30.1xx 密码hygd123 找到下面路径中的文件 cd /home/weblogic/Oracle/Middleware/user_projects/domains/base_domain/bapp-logs 查看log日志 tail -f -n 400 Adminservers.log oracle删除表空间&#xff08;切换到dba用户…

家庭宽带的ip地址是固定的吗?宽带ip地址怎么修改‌

在家庭网络环境中&#xff0c;IP地址的分配和管理是用户常关注的问题。本文将探讨家庭宽带IP地址的固定性&#xff0c;并介绍如何修改宽带IP地址&#xff0c;以满足用户的不同需求。 一、家庭宽带的IP地址是否固定? 关于家庭宽带的IP地址是否固定&#xff0c;答案并非一概而论…

【深入学习Redis丨第八篇】详解Redis数据持久化机制

前言 Redis支持两种数据持久化方式&#xff1a;RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上&#xff0c;后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用&#xff0c;但是通常会将两者结合使用。 一、持久化 1.1、什么…

【Android】使用 Compose 自定义 View 实现从 0 ~ 1 仿 EChat 柱状图

目录 前言DrawScopeDrawScope Api 绘制柱状图绘制 X 轴绘制 Y 轴绘制柱状背景绘制柱状前景完整代码最终效果 存在的问题 前言 本文讲的是使用 compose 去自定义 View &#xff0c;如果您未曾通过继承 View 的方式去实现自定义 View&#xff0c;那么&#xff0c;我建议在观看本…