ClassLoader
### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`不仅管理着类的加载过程,而且其设计模式还对Java的安全性和性能有着至关重要的影响。 #### 二、类的生命周期与加载阶段 类的生命周期包括加载、验证、准备、解析、初始化五个阶段。其中,加载阶段是最初始的阶段,主要由`ClassLoader`完成。在这个阶段,`ClassLoader`负责完成以下三项基本工作: 1. **通过一个类的全限定名来获取该类的二进制字节流**。 2. **将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构**。 3. **在Java堆中生成一个代表这个类的`java.lang.Class`对象**,作为方法区这些数据的访问入口。 #### 三、Java中类加载器的几种方法 1. **`loadClass`**: 遵循双亲委托机制,尝试加载指定类。此方法先检查是否已经加载过此类,然后尝试从父类加载器加载,最后尝试自身加载。 2. **`findClass`**: 当`loadClass`方法无法加载类时,会调用此方法来查找并处理类。 3. **`findLoadedClass`**: 查找已经加载过的类,以避免重复加载。 4. **`defineClass`**: 将字节流转换为类的实例,完成类的定义。 5. **`getParent`**: 获取父类加载器,用于实现双亲委托机制。 #### 四、双亲委托机制详解 双亲委托机制是`ClassLoader`体系中的一个重要特性,它确保了核心库的加载只由顶层的启动类加载器进行。这一机制的工作流程如下: 1. **当一个类加载器收到类加载请求时**,它首先不会尝试自己去加载这个类,而是将这个请求委托给父类加载器。 2. **如果父类加载器能够加载这个类**,则直接返回;否则,父类加载器再将请求传给它的父类加载器,依次递归,直到顶层的启动类加载器。 3. **如果顶层类加载器也无法加载**,则类加载请求向下传递,最终到达最初收到类加载请求的类加载器。 4. **如果此时类仍未加载成功**,则类加载器尝试通过自己的`findClass`方法去加载。 ##### 双亲委托机制的优点: 1. **安全性**: 如果没有双亲委托机制,那么自定义的类加载器就可以轻易地替换掉核心类库中的类,这将带来极大的安全隐患。 2. **避免重复加载**: 由于每个类加载器都有一个缓存机制,因此在同一个类加载器环境下不会出现多次加载相同类的情况。 #### 五、Java类加载器层次结构 Java类加载器主要包括三种类型: 1. **启动(Bootstrap)类加载器**: - 实现方式: 本地代码(C++) - 加载内容: `<Java_Runtime_Home>/lib`下的核心类库,如`rt.jar`等。 - 特点: 开发者无法直接获取到启动类加载器的引用,因此无法直接操作。 2. **标准扩展(Extension)类加载器**: - 实现方式: `sun.misc.Launcher$ExtClassLoader` - 加载内容: `<Java_Runtime_Home>/lib/ext`或由`java.ext.dirs`系统变量指定的位置中的类库。 - 特点: 开发者可以直接使用标准扩展类加载器。 3. **系统(System)类加载器**: - 实现方式: `sun.misc.Launcher$AppClassLoader` - 加载内容: 系统类路径(`CLASSPATH`)中指定的类库。 - 特点: 开发者可以直接使用系统类加载器。 #### 六、Android中的ClassLoader 在Android环境中,主要使用的`ClassLoader`有`PathClassLoader`和`DexClassLoader`。 1. **`PathClassLoader`**: - 继承自`BaseDexClassLoader`。 - 主要用于应用程序本身的类加载。 2. **`DexClassLoader`**: - 同样继承自`BaseDexClassLoader`。 - 用于加载来自外部的Dex文件,常用于热更新、插件化等场景。 ##### 构造方法示例: - `PathClassLoader`: ```java public PathClassLoader(String dexPath, ClassLoader parent) { super(dexPath, null, null, parent); } public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) { super(dexPath, null, librarySearchPath, parent); } ``` - `DexClassLoader`: ```java public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) { super(dexPath, new File(optimizedDirectory), librarySearchPath, parent); } ``` #### 七、总结 通过对`ClassLoader`的基本概念、工作原理、双亲委托机制以及不同类型的类加载器的了解,我们可以更好地理解Java类加载的过程及其背后的设计哲学。这对于深入理解Java虚拟机的内部机制以及开发高质量的应用程序都至关重要。
剩余16页未读,继续阅读
- 粉丝: 3
- 资源: 28
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助