ClassLoader类加载的示例分析
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍了ClassLoader类加载的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java类加载器1、BootCl
千家信息网最后更新 2026年11月01日ClassLoader类加载的示例分析
这篇文章主要介绍了ClassLoader类加载的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
Java类加载器
1、BootClassLoader: 用于加载Android Framework层class文件。
2、PathClassLoader: 用于Android应用程序类加载器。可以加载指定的dex,jar、zip、zpk中的classes.dex
3、DexClassLoader:加载指定的dex,以及jar、zip、apk中的classes.dex

源码解析
1.ClassLoader中提供loadClass用于加载指定类
//ClassLoader.javapublic Class> loadClass(String name) throws ClassNotFoundException { //该处调用了两个参数的重载方法 return loadClass(name, false); } protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException { //先查一下该类是否已经加载过了 Class> c = findLoadedClass(name); if (c == null) { try { //双亲委托机制,先让爸爸去找 if (parent != null) { c = parent.loadClass(name, false); } else { //如果parent为null,则用BootClassLoader进行加载 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { //如果都找不到就自己去找,此方法在子类BaseDexClassLoader类中有重写 c = findClass(name); } } return c; }2.BaseDexClassLoader类中对findClass有重写,也是实际会使用执行的
//BaseDexClassLoader.java//查找class @Override protected Class> findClass(String name) throws ClassNotFoundException { ... //这里通过pathList变量来查找,而pathList是在BaseDexClassLoader的构造方法中初始化的 Class c = pathList.findClass(name, suppressedExceptions); ... return c; } private final DexPathList pathList;public BaseDexClassLoader(String dexPath, File optimizedDirectory, String librarySearchPath, ClassLoader parent, boolean isTrusted) { super(parent); //构造方法中初始化pathList变量 this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted); }3.BaseDexClassLoader中是通过调用DexPathList中的findClass来实现的,那么接下来我们分析一下DexPathList是怎么实现的
//DexPathList.java//是一个Element数组,一个element中包含一个 DexFile,DexFile就代表一个Dex文件,里面的native(C/C++)函数来进行Dex的加载工作 private Element[] dexElements; public Class> findClass(String name, Listsuppressed) { for (Element element : dexElements) { //此处调用Element的findClass来实现, Class> clazz = element.findClass(name, definingContext, suppressed); if (clazz != null) { return clazz; } } return null; }// Element为DexPathList的内部类static class Element { private final File path; //一个DexFile就代表一个Dex文件 private final DexFile dexFile; //有多个构造方法,但都仅是将值传过来,让Element来持有一个DexFile public Element(DexFile dexFile) { this.dexFile = dexFile; this.path = null; } public Class> findClass(String name, ClassLoader definingContext, List suppressed) { //通过DexFile来加载类 return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed) : null; } }DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory, boolean isTrusted) { //通过makeDexElements方法为dexElements初始化 this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext, isTrusted);}//腾讯系的热修复,诸如微信tinker、qq空间qfix原理便是反射此方法,将修复后的类打包成dex,通过反射该方法来将文件转化为Element,并将新生成的element放到dexElements前面,这样下次系统再去寻找某个class时,会先从修复后的dex中来找class,找到后便不再继续查找,从而修复该class,此方式便为插桩private static Element[] makeDexElements(List files, File optimizedDirectory, List suppressedExceptions, ClassLoader loader, boolean isTrusted) { Element[] elements = new Element[files.size()]; ... for (File file : files) { if (name.endsWith(DEX_SUFFIX)) { //以 .dex 结尾的 // Raw dex file (not inside a zip/jar). //加载dex文件 dex = loadDexFile(file, optimizedDirectory, loader, elements); if (dex != null) { elements[elementsPos++] = new Element(dex, null); } } } ... return elements; }private static DexFile loadDexFile(File file, File optimizedDirectory, ClassLoader loader, Element[] elements) throws IOException { if (optimizedDirectory == null) { return new DexFile(file, loader, elements); } else { String optimizedPath = optimizedPathFor(file, optimizedDirectory); return DexFile.loadDex(file.getPath(), optimizedPath, 0, loader, elements); } }
4.这里通过 new DexFile 或者 loadDex方法来创建DexFile,两者类似,那我们拿new DexFile 来举例分析
//DexFile.javaprivate DexFile(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { ... //此处调用openDexFile来实现 mCookie = openDexFile(sourceName, outputName, flags, loader, elements); ... }private static Object openDexFile(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { //此处通过调用 openDexFileNative来实现 return openDexFileNative(new File(sourceName).getAbsolutePath(), (outputName == null) ? null : new File(outputName).getAbsolutePath(), flags, loader, elements); }//openDexFileNative是一个native方法,是由C/C++来实现的private static native Object openDexFileNative(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements);感谢你能够认真阅读完这篇文章,希望小编分享的"ClassLoader类加载的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
方法
文件
分析
篇文章
示例
代表
变量
此方法
反射
接下来
两个
价值
兴趣
函数
原理
参数
双亲
同时
多个
子类
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
伟宏互联网科技
科技服务与互联网
互联网与新科技
互联网与未来科技
唐信互联网科技
南京欣网互联网科技
赫美联合互联网科技
齐家互联网科技有限公司
现代科技和互联网有关系吗
科技与互联网的利与弊
宁波青枫互联网科技有限公司
中国的互联网科技企业的崛起
互联网科技实习生岗位职责
湖南诚度互联网科技有限公司
互联网为啥属于高科技
世界互联网科技公司市值排名
昭通互联网科技选哪家
富国互联网科技002692
互联网科技创新方面的资料
现代科技的标志之一的互联网
互联网金融科技
中关村互联网科技集团
重庆互联网络科技
狮子座互联网科技有限公司
百单互联网科技有限公司
有木互联网科技
互联网科技美容
深圳期待互联网科技
多迪互联网科技有限公司
互联网科技素材视频竖屏