### JVM 类加载机制与双亲委派模型 #### 一、概述 JVM(Java Virtual Machine,Java虚拟机)中的类加载机制是一项重要的基础技术,它不仅涉及到了类的加载过程,还涉及到类如何被正确识别及加载的问题。类加载器(ClassLoader)是JVM的一部分,用于将编译好的类文件加载到内存中,并负责解析类文件中的常量池入口,将其转换为内存中的数据结构。类加载器的设计遵循了一个被称为“双亲委派”模型的原则,这种设计方式确保了Java平台的安全性和稳定性。 #### 二、JDK 默认提供的 ClassLoader JDK默认提供了三种类加载器,它们分别是: 1. **BootStrap ClassLoader**(启动类加载器):这是Java类加载层次中最顶层的类加载器,使用C++编写而成,负责加载JDK的核心类库,例如`rt.jar`、`resources.jar`、`charsets.jar`等。这些核心类库包含了Java语言的基本类,如`String`、`Object`等,对于Java程序而言是不可或缺的基础部分。 2. **Extension ClassLoader**(扩展类加载器):负责加载Java的扩展类库,默认情况下会加载`JAVA_HOME/jre/lib/ext/`目录下的所有jar包。扩展类加载器是由BootStrap ClassLoader加载的,并且它的父类加载器被设置为BootStrap ClassLoader。通过这种方式,扩展类加载器能够访问核心类库的功能。 3. **App ClassLoader**(应用类加载器):也被称为系统类加载器,负责加载用户应用程序的类路径(classpath)中的所有jar和class文件。用户程序通常都是通过这个类加载器来加载自己的类。 除了这三种默认的类加载器之外,JDK还支持自定义类加载器。自定义类加载器可以实现特定的类加载策略,比如从数据库或网络加载类文件等。 #### 三、双亲委派模型 类加载过程中使用的双亲委派模型是一种重要的机制,它保证了类的唯一性,并有效地解决了类加载安全性问题。 1. **双亲委派的工作流程**: - 当一个类加载器收到类加载请求时,它首先不会尝试自己加载该类,而是先将这个请求委托给父类加载器去完成,每上一级都按照同样的方式委托。 - 如果父类加载器可以完成类加载任务,则返回加载的类;如果父类加载器无法完成加载,则子类加载器才会尝试自己加载该类。 - 这个过程从最顶层的BootStrap ClassLoader开始,依次向下传递,直到找到能够加载该类的类加载器。 2. **双亲委派的优势**: - **安全性**:由于Java核心API类总是被BootStrap ClassLoader加载,因此这种方法可以防止恶意代码覆盖标准的Java库。 - **高效性**:避免了重复加载相同的类,提高了系统的性能。 - **统一性**:保证了所有的类都是通过相同的类加载器实例加载的,这对于判断两个类是否相同是非常关键的。 #### 四、自定义 ClassLoader 在某些特殊的应用场景下,可能需要创建自定义的类加载器以实现特定的需求。为了自定义类加载器,通常的做法是继承`java.lang.ClassLoader`类,并重写`findClass`方法。如果要完全改变双亲委派的机制,则需要重写`loadClass`方法。 以下是一个简单的自定义类加载器示例: 1. **创建测试类**: ```java package classLoad; public class Test { public static void main(String[] args) {} public String getStr() { System.out.println("ceshi"); return "ceshi"; } } ``` 2. **创建自定义类加载器**: ```java package classLoad; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; public class NetworkClassLoader extends ClassLoader { private String rootUrl; // 指向类文件的URL public NetworkClassLoader(String rootUrl) { super(); this.rootUrl = rootUrl; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // 实现从网络或其他途径加载类文件的过程 // 这里简化处理,实际应用中需要根据实际情况进行编码和处理 Class<?> clazz = null; URL url = new URL(rootUrl); InputStream in = url.openStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i; while ((i = in.read()) != -1) { baos.write(i); } byte[] data = baos.toByteArray(); clazz = defineClass(name, data, 0, data.length); return clazz; } } ``` 通过以上步骤,我们可以创建一个自定义的类加载器,从而实现从网络或其他来源加载类文件的需求。 #### 五、总结 JVM中的类加载机制与双亲委派模型是Java运行时环境的基础组成部分。了解这些原理可以帮助开发者更好地理解Java应用程序是如何加载和执行的,同时也为解决类加载相关的故障提供了理论依据。自定义类加载器则进一步增强了Java平台的灵活性,使得开发者可以根据具体需求实现更复杂的类加载逻辑。
































- 粉丝: 6
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 国内智慧城市建设方案调研.docx
- 海东市和谐路桥监理规划.doc
- 国际工程索赔-3-FIDIC合同条件及其索赔条款.ppt
- 3dmax三维设计教程.doc
- 实验13电动势的测定.doc
- 砌体工程合同(标准).doc
- 南翔现代企业园F地块厂房桩基工程技术交底记录.doc
- 楼层排水管道安装的技术交底.doc
- 小班科学活动-叮叮当.doc
- 混凝土内墙、顶抹灰分项工程质量管理.doc
- 箱梁悬浇高程控制程序图.doc
- 桥梁工程施工标准化技术推广示例.ppt
- XX年主板接口技术的基本知识.doc
- 美术--爱吃糖葫芦的太阳公公.doc
- 中建某局二公司劳务分包管理程序.doc
- 【新教材】高中数学湘教版必修第一册课件432-对数的运算法则.pptx


