你了解 Java 的类加载器吗?
Java 类加载器(ClassLoader)
Java 中的类加载器是用于加载 .class 文件到 JVM 中的组件,它的核心作用是将字节码(.class 文件)加载到内存,并且使它能够被 JVM 执行。类加载器决定了类的加载顺序和加载方式,是 Java 应用程序在运行时执行的重要部分。
1. 类加载器的基本概念
- 类加载器:Java 中的类加载器用于将
.class文件加载到 JVM 中,并将其转化为一个Class对象,之后该Class对象可以用于反射等操作。 - 每个类加载器都具备加载类的能力,但它们的加载范围和加载顺序可能不同。
2. 类加载器的类型
2.1 根类加载器(Bootstrap ClassLoader)
- 作用:是最顶层的类加载器,负责加载 Java 核心库中的类,如
java.lang.*和java.util.*。 - 实现:Bootstrap ClassLoader 是由 C++ 实现的,通常由操作系统提供,加载
jre/lib目录下的类库。 - 加载路径:由环境变量
sun.boot.class.path指定。
2.2 扩展类加载器(Extension ClassLoader)
- 作用:负责加载 JDK 中的扩展类库,主要加载
jre/lib/ext目录下的类库。 - 实现:它是由 Java 实现的,继承自
ClassLoader。 - 加载路径:由
java.ext.dirs指定。
2.3 系统类加载器(System ClassLoader)
- 作用:也叫应用类加载器,负责加载应用程序的类路径(
classpath)下的类。 - 实现:由 Java 实现,通常是用户应用程序使用的加载器,加载
classpath中的类。 - 加载路径:由环境变量
java.class.path指定。
2.4 自定义类加载器(Custom ClassLoader)
- 作用:开发人员可以自定义类加载器,继承
ClassLoader类,重写findClass()方法来加载类。 - 应用场景:
- 加载本地文件、数据库、网络等外部资源中的类。
- 用于 Web 服务器(如 Tomcat)中动态加载 JSP 文件或动态加载插件等。
3. 类加载的过程
3.1 加载(Load)
- 类加载器根据类名查找
.class文件,并读取它的字节流。 - 这个过程会依赖于类加载器的父子关系,父加载器优先加载。
3.2 链接(Linking)
链接分为三个阶段:
- 验证(Verify):检查字节码是否符合 JVM 的要求,防止非法代码进入。
- 准备(Prepare):为类的静态变量分配内存并赋默认值。
- 解析(Resolve):将常量池中的符号引用替换为直接引用。
3.3 初始化(Initialize)
- 在类的初始化阶段,JVM 执行类的静态代码块(
static块),初始化静态变量等。
4. 类加载器的双亲委派机制(Parent Delegation Model)
- 双亲委派模型是 Java 类加载器的一个重要特点,它确保了类加载的安全性和稳定性。
- 原理:
- 每个类加载器都有一个父类加载器。当一个类加载请求发生时,子加载器会先将请求传递给父加载器,父加载器先尝试加载该类。如果父加载器加载失败,子加载器再尝试加载。
- 这确保了 Java 核心类库(如
java.lang.*)始终由根类加载器加载,从而避免了重复加载和潜在的冲突。
5. 自定义类加载器的示例
通过继承 ClassLoader 类,我们可以创建自己的类加载器,下面是一个简单的自定义类加载器示例:
public class MyClassLoader extends ClassLoader {
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = loadClassData(name); // 从某个源(如文件、数据库)获取字节数据
return defineClass(name, classData, 0, classData.length);
}
private byte[] loadClassData(String name) {
// 加载类的字节数据(例如,从文件或网络中读取)
return new byte[0]; // 示例返回空字节数组
}
}
public class Test {
public static void main(String[] args) throws Exception {
MyClassLoader loader = new MyClassLoader();
Class<?> clazz = loader.loadClass("com.example.MyClass");
Object obj = clazz.newInstance();
}
}
解释:
- MyClassLoader 继承自 ClassLoader,重写 findClass 方法来从某个地方加载类的字节数据。
- loadClassData 方法是我们用来加载类字节数据的地方,可以从文件、数据库等地方加载。
- defineClass 方法将字节数据转换为一个 Class 对象。
6. 类加载器的应用场景
- 动态加载插件:在应用程序运行时,动态加载新的功能模块或插件,避免重新启动应用。
- Web 服务器:如 Tomcat 会使用不同的类加载器来加载 Web 应用中的类,保证每个应用使用独立的类加载器。
- 类版本控制:在某些情况下,自定义类加载器可以用来控制不同版本的类加载,避免类冲突。
7. 总结
- 类加载器是 Java 中用于加载 .class 文件的组件,分为根类加载器、扩展类加载器、系统类加载器和自定义类加载器。
- 双亲委派机制保证了类加载的顺序和安全性。
- 自定义类加载器为我们提供了灵活性,可以从本地文件、网络等加载类,支持插件化开发。
你了解 Java 的类加载器吗?的更多相关文章
- java自定义类加载器
前言 java反射,最常用的Class.forName()方法.做毕设的时候,接收到代码字符串,通过 JavaCompiler将代码字符串生成A.class文件(存放在classpath下,也就是ec ...
- Java虚拟机类加载器及双亲委派机制
所谓的类加载器(Class Loader)就是加载Java类到Java虚拟机中的,前面<面试官,不要再问我"Java虚拟机类加载机制"了>中已经介绍了具体加载class ...
- 深入探讨java的类加载器
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1.0 就出现了,最初是为了满足 Ja ...
- java 中类加载器
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式. java 中类加载器分为三个: BootstrapClassLoader 负责加载 ${ ...
- java高新技术-类加载器
1.类加载器及委托机制的深入分析 > 类加载器的作用:一个java文件中的出现的类,首先要把这个类的字节码加载到内存中,这个类的信息放在硬盘的classPath下的class文件中, 把cla ...
- 深入理解Java虚拟机 - 类加载器
引子: 类加载器(classloader)是独立于虚拟机之外,可以独立实现的代码模块. OSGi使用了类加载器的这一特点实现其热插拔的特性 Java同C++等语言不通, ...
- 分析Java的类加载器与ClassLoader(二):classpath与查找类字节码的顺序,分析ExtClassLoader与AppClassLoader的源码
先回顾一下classpath classpath的作用: classpath的作用是指定查找类的路径:当使用java命令执行一个类(类中的main方法)时,会从classpath中进行查找这个类. 指 ...
- java面向对象--类加载器及Class对象
类加载器 jvm 和 类的关系 当调用 java命令运行一个java程序时,会启动一个java虚拟机进程.同一个jvm的所有线程.所有变量都处于同一个进程里,都使用该jvm进程的内存区. jvm进程终 ...
- Java的类加载器
一.类加载器的概念 类加载器(class loader)用来加载 Java 类到 Java 虚拟机中.一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 ...
- Java的类加载器种类(双亲委派)
Java类加载器采用双亲委派模型: 1.启动类加载器:这个类加载器负责放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别 ...
随机推荐
- Access pg walkthrough Intermediate window域渗透
namp nmap -p- -A -sS -T4 192.168.200.187 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-23 00 ...
- 「CF1101F」Trucks and Cities
题意描述 有 \(N\) 座城市,第 \(i\) 座坐标为 \(a_i\) ,有 \(M\) 辆卡车,第 \(i\) 辆卡车要从城市 \(s_i\) 前往城市 \(e_i\) ,每单位长度耗油量为 \ ...
- overflow秒解外边距合并以及浮动导致的元素塌陷问题
外边距导致的合并问题: 1 处于一上一下位置的两个块级元素 在同时各自设置了上下边距时,二者间的外边距通常以 数值较大的一个作为两者间的外边距 而不是简单的数值相加 .box2{ width: 100 ...
- [文件格式/数据存储] Parquet:开源、高效的列式存储文件格式协议
序:缘起 => 用 java 读取 parquet 文件 生产环境有设备出重大事故,又因一关键功能无法使用,亟需将生产环境的原始MQTT报文(以 parquet 文件格式 + zstd 压缩格式 ...
- LangChain基础篇 (04)
LangChain 核心模块:Data Conneciton - Document Loaders 使用文档加载器从源中加载数据作为文档.一个文档是一段文字和相关的元数据. 如,有用于加载简单 .tx ...
- 你还不会使用curl发送请求吗?一篇博客搞定!
前言:以下均为Windows使用,使用前不需要任何准备,打开命令提示符根据指令即可使用关键字: curl 注意: 建议在请求前ping一下 ping http://www.123.com 或 ping ...
- 库卡机器人KR500维修保养
随着现代工业自动化,KUKA库卡机器人以其卓越的性能.灵活的操作和高效的产出而备受赞誉.然而,为了确保机器人的持续稳定运行和延长使用寿命,应联系子锐机器人维修对库卡机器人保养至关重要. 一.库卡机器人 ...
- 工业机器人维修保养|ABB机器人IRB 6700维修保养技巧
通过机器人维修保养服务定制合理的维修保养工作,可以确保ABB机器人IRB 6700的持续稳定运行,延长其使用寿命,为企业的生产提供有力保障. 一.ABB机器人IRB 6700日常检查与维护 外观检查: ...
- [Jaav SE/程序生命周期] 优雅的Java应用程序的启停钩子框架
序 了解 spring 生态及框架的 java er 都知道,spring 应用的生命周期管理及配套接口较为优雅.可扩展. 但脱离 spring 的 java 应用程序,如何优雅地启停.管理程序的生命 ...
- 2024年最新iOS 17屏蔽系统更新方法,iPhone、iPad通用!
到Safari浏览器打开,描述文件会自动安装进手机里. 这时候我们在设置里,找到设备管理,点击刚刚下载好的描述文件,进行安装.要注意看,有苹果的签名,才说明是官方出品,千万要注意哦!安装完成后,重启手 ...