Appearance
说下类加载器机制与双亲委派
Java 的类加载器机制与双亲委派模型是 Java 虚拟机(JVM)加载类文件时采用的一种体系结构。它用于确保 Java 应用程序中类的单一性、安全性和加载顺序。
类加载器机制
Java 的类加载器机制负责将类的字节码从各种来源(例如本地文件系统、网络等)加载到 JVM 中。主要的类加载器包括:
- Bootstrap ClassLoader:引导类加载器,负责加载核心 Java 库,由 JVM 自身实现(如
rt.jar)。 - Extension ClassLoader:扩展类加载器,加载扩展库,通常从
java.ext.dirs系统属性指定的目录中加载。 - Application ClassLoader:系统类加载器,加载用户类路径(
classpath)中定义的类。
双亲委派模型
双亲委派模型是类加载机制的一种实现策略,确保类的唯一性和安全性。其工作流程如下:
- 当一个类加载器接收到类加载请求时,它首先将请求委派给它的父类加载器去加载。
- 只有当父加载器无法完成加载任务时,子加载器才会尝试自己去加载该类。
这种机制确保了 Java 核心类始终由 Bootstrap ClassLoader 加载,防止重复加载和安全漏洞。
代码示例
以下是一个简单的示例,展示如何自定义类加载器并观察双亲委派模型的工作:
java
import java.io.*;
public class CustomClassLoader extends ClassLoader {
private String classPath;
public CustomClassLoader(String classPath) {
this.classPath = classPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = loadClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, classData, 0, classData.length);
}
}
private byte[] loadClassData(String className) {
String path = classPath + "/" + className.replace('.', '/') + ".class";
try (InputStream is = new FileInputStream(path); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
try {
// 设定自定义类加载器的路径
String classPath = "/path/to/classes";
CustomClassLoader customClassLoader = new CustomClassLoader(classPath);
// 从自定义路径加载类
Class<?> loadedClass = customClassLoader.loadClass("MyClass");
System.out.println("Class " + loadedClass.getName() + " loaded by " + loadedClass.getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}解释
- 自定义类加载器:
CustomClassLoader实现了从给定路径加载类的逻辑,通过重写findClass方法实现。 - 双亲委派:当
loadClass调用时,首先会尝试委托给父类加载器加载类。 - 类路径加载:通过
loadClassData方法实现从文件系统读取类数据。
总结
- 安全性:双亲委派模型帮助防止加载非法类或重复类,保证核心库的安全。
- 扩展性:自定义类加载器允许开发者改变类加载行为(如从数据库、网络等加载类),在插件系统中非常有用。
- 单一性:确保核心类由一个统一的类加载器进行加载,避免冲突和不一致。在大多数情况下,开发者不需要实现自己的类加载器,但了解它的机制对于深入理解 Java 执行环境是十分有益的。
更新: 2024-08-09 16:01:44
原文: https://www.yuque.com/tulingzhouyu/db22bv/hgkf3zbuut09l7ig
短视频
没想到啊,现在还有人不知道 什么是双亲委派机制?哈喽, 大家好,我是 JJ,
双亲委派机制是 Java 类加载器的一种工作机制,用于保证 Java 类的安全性和一致性。
它基于一种层次结构的加载器体系,按照一定的规则从顶层到底层依次加载类,如果某个类需要被加载,
首先会委托给顶层的类加载器进行加载,如果顶层加载器无法加载,就会依次向下委托,直到找到能够加载该类的类加载器为止。
具体来说,就是当一个类加载器收到加载类的请求时,它会先检查是否已经加载了该类,如果没有就将请求委托给其父加载器。
父加载器接着会重复相同的过程,直到顶层的启动类加载器。
如果顶层的启动类加载器仍无法加载该类,那么会回溯到发起请求的类加载器,由该类加载器尝试加载。
双亲委派机制的好处在于可以确保 Java 类的唯一性和一致性,避免了同名类的冲突,同时也防止了恶意代码的加载。
比如说,Java 核心类库中的类都是由启动类加载器加载的,而自定义的类通常是由自定义的类加载器加载,这样就能够确保自定义的类不会覆盖核心类库中的类。
更新: 2024-06-06 22:34:09
原文: https://www.yuque.com/tulingzhouyu/db22bv/ugx1wuy09dufgn61