您好,登录后才能下订单哦!
# 何为双亲委派
## 引言
在Java虚拟机(JVM)的类加载机制中,"双亲委派模型"(Parent Delegation Model)是一个核心概念。它不仅是Java安全模型的基石,也是保证Java程序稳定运行的重要机制。本文将深入探讨双亲委派的概念、工作原理、实现细节、优势与局限性,以及在实际开发中的应用场景。
## 一、类加载器基础
### 1.1 类加载器的作用
类加载器(ClassLoader)是JVM用来动态加载类的子系统,主要职责包括:
- 读取.class文件的二进制数据
- 将字节流转换为方法区中的运行时数据结构
- 在堆中生成对应的Class对象
### 1.2 Java内置类加载器
JVM默认提供三类加载器:
1. **Bootstrap ClassLoader**(启动类加载器)
- 由C++实现,无Java对应类
- 加载<JAVA_HOME>/lib目录的核心类库
2. **Extension ClassLoader**(扩展类加载器)
- 继承URLClassLoader
- 加载<JAVA_HOME>/lib/ext目录的扩展类
3. **Application ClassLoader**(应用类加载器)
- 又称System ClassLoader
- 加载用户类路径(CLASSPATH)上的类
```java
// 查看类加载器示例
public class ClassLoaderDemo {
public static void main(String[] args) {
System.out.println(String.class.getClassLoader()); // null(Bootstrap加载)
System.out.println(com.sun.crypto.provider.DESKeyFactory.class.getClassLoader()); // ExtClassLoader
System.out.println(ClassLoaderDemo.class.getClassLoader()); // AppClassLoader
}
}
双亲委派模型要求: 1. 除顶层启动类加载器外,每个类加载器都有父加载器 2. 加载类时先委派给父加载器尝试加载 3. 父加载器无法完成时才自己尝试加载
graph TD
A[自定义类加载器] --> B[AppClassLoader]
B --> C[ExtClassLoader]
C --> D[BootstrapClassLoader]
D -->|无法加载| C
C -->|无法加载| B
B -->|无法加载| A
具体步骤: 1. 收到类加载请求后,先检查是否已加载 2. 未加载则调用父加载器的loadClass() 3. 父加载器同样递归委派 4. 直到BootstrapClassLoader 5. 若所有父加载器都无法完成,抛出ClassNotFoundException 6. 子加载器尝试自己加载
以ClassLoader.loadClass()为例:
protected Class<?> loadClass(String name, boolean resolve) {
synchronized (getClassLoadingLock(name)) {
// 1. 检查是否已加载
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
// 2. 父加载器不为null则委派
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// 3. 父加载器为null则委托Bootstrap
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 父加载器无法完成
}
if (c == null) {
// 4. 自行查找类
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
// 典型SPI加载模式
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class, cl);
实现步骤: 1. 继承java.lang.ClassLoader 2. 重写findClass()而非loadClass() 3. 建议维护类加载器缓存
public class CustomClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) {
byte[] classData = loadClassData(name);
return defineClass(name, classData, 0, classData.length);
}
private byte[] loadClassData(String className) {
// 自定义加载逻辑...
}
}
LinkageError
ClassCastException
(MyInterface)obj
抛出异常NoClassDefFoundError
双亲委派模型作为Java类加载的核心机制,二十多年来保证了Java生态的稳定运行。虽然在新特性(如模块化)面前有所调整,但其设计思想仍深刻影响着JVM架构。理解这一机制不仅有助于解决日常开发中的类加载问题,更能帮助开发者设计出更健壮、安全的Java应用。
”`
注:本文实际字数约2700字,内容涵盖技术原理、源码分析、实践应用等多个维度,可根据需要进一步扩展具体案例或调整技术细节的深度。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。