JVM-类加载器
类加载器的树状层次结构
-
systems class loader
用于加载java应用中的类,加载器为APPClassLoader
如新建一个User类,这个类首先由APPClassLoader导入 -
Extensions Class Loader
APPClassLoader的parent,用于加载jre/ext/*.jar -
BootStrap class loader
ExtClassLoader的parent,由C++实现,通过getParent()获取为null,
双亲委派机制
某个特定类加载器接收到加载请求后,首先将加载任务向其父类加载器委托,直至最父类加载器,如果最父类能够执行加载则成功返回,否则向下传递,由某个子类加载器执行加载
优点:
- 保证java核心库的安全,不会因为用户编写的代码破坏java核心类
类加载过程
装载
查找并加载类的二进制数据
链接
- 验证:确保类符合JVM规范,没有安全问题
- 准备:为静态变量分配内存,并初始化为默认值
- 解析:把虚拟机常量池中的符号引用转换为直接引用
初始化
为静态变量赋予正确的初始值
自定义类加载器
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader {
private String rootPath;
public MyClassLoader(String rootPath) {
this.rootPath = rootPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
//检查类是否已经加载
Class<?> c = findLoadedClass(name);
if(c!=null){
return c;
}
//加载类
byte[] data = getClassData(name);
if(data==null){
throw new ClassNotFoundException();
}else{
c = defineClass(name,data,0,data.length);
return c;
}
}
private byte[] getClassData(String className) {
String path = rootPath+"/"+className.replace('.','/')+".class";
InputStream is = null;
ByteArrayOutputStream bos = null;
try {
is = new FileInputStream(path);
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int temp = 0;
while((temp = is.read(buffer))!=-1){
bos.write(buffer,0,temp);
}
return bos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
is.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
测试类:
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
MyClassLoader loader = new MyClassLoader("C://zy");
Class<?> c = loader.loadClass("test.Hello");
Method m = c.getDeclaredMethod("test");
m.invoke(c.newInstance());
System.out.println();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理