双亲委派模型
类加载流程
类加载流程,先加载Bootstrap ClassLoader 启动类加载即最顶层的加载类。这部分由C++ 编写。
继续再次加载Extention ClassLoader 扩展类加载器由Bootstrap ClassLoader加载,加载进入内存。
继续再次加载Application ClassLoader 应用类加载器,即系统即在此,加载当前应用下的类
最后再次加载ClassLoader类
双亲委派模型
该模型是先检查指定名称的类是否已经加载过,如果加载进入内存,不加载直接返回,如果没有加载过,判断是否有父类加载器,如果拥有父类加载器,那么将会直接将权利移交给父类,由父类代理当前类进行加载该类。或者是调用C++的bootstrap类加载器来加载该类
最后如果三者都没有找到类,那么直接调用当前类加载器的findClass方法来完成类加载。
即,如果需要需要加载自定义的类,那么就需要重写findClass方法。
即,如果需要将当前类加载进入,那么就需要重写findClass方法,若未找到这几种类,则会自动调用findClass方法。
调用过程
先加载父类,若父类未加载,继续调用父类,直到bootstrap查看是否已经加载,如果此时都未加载类,那么将会使用自定义的ClassLoader 然后调用自定义的ClassLoader的findClass方法,用于将字节码加载进入内存。最后返回该class的描述符
栗子
public class Test { public void helloWorld(){ System.out.println("me loader" + getClass().getClassLoader().getClass()); // 先调用getClass获取当前类的对象的描述,然后再次调用getClassLoader()获取加载的父类,再次调用getClass()获取加载进入的父类的名称 } }
此时如果该类这这个项目里的里的话,会由Application加载当前应用类下的类。
由类的加载过程可知,当未找到类的时候,会加载类的ClassLoader类,此时需要定义一个类,让该类继承ClassLoader类,由于该类是ClassLoader的子类,此时会自动加载该类,由于该类不在内存当中,所以需要使用static,让其一开始加载进入内存当中。
代码如下
import java.io.FileInputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main { // 需要使用static让其加载进入内存 static class myClassLoader extends ClassLoader{ private String classPath; // 获取当前类的在磁盘中保存的地址 // 通过构造函数将地址注入 public myClassLoader(String classPath){ this.classPath = classPath; } // 将文件内容加载进入内存 private byte[] loadByte(String name) throws Exception{ // 获取一个输入流, FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class"); // 获取长度 int len = fis.available(); // 定义byte数组 byte[] data = new byte[len]; // 加载进入内存 fis.read(data); // 关闭流 fis.close(); return data; } // 重写findClass方法,让加载的时候调用findClass方法 protected Class<?> findClass(String name) throws ClassNotFoundException{ try{ // 读取文件到数组中 byte[] data = loadByte(name); // 将字节码加载进入内存当中 return defineClass(name, data, 0, data.length); }catch(Exception e){ e.printStackTrace(); } return null; } } public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException { // 先初始化该类 myClassLoader classLoader = new myClassLoader("/home/ming"); // 此时会调用findClass加载Test.class加载进入内存当中 Class clazz = classLoader.loadClass("Test"); // 实例化该类对象 Object obj = clazz.newInstance(); // 获取clazz该类方法中名称为hello,参数为空的方法。 Method helloMethod = clazz.getDeclaredMethod("helloWorld", null); // 调用该方法 // 调用obj类中的helloMethod,参数为空的方法。 helloMethod.invoke(obj, null); } }
实验结果
me loaderclass Main$myClassLoader Process finished with exit code 0

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Node.js之Buffer
Node.js之Buffer 什么是 Buffer 如同官方 API 中介绍的那样,在 ES6 引入 TypedArray 之前,JavaScript 没有读取或者操作二进制数据流的机制。 Buffer 类作为 NodeJS API 的一部分被引入,以便能够和 TCP 等网络流和文件流等进行交互。 现在 TypedArray 已经被添加到了 ES6 中,Buffer 类以一种更优化和适用于 NodeJS 操作的方式实现了 Unit8Array API。 总而言之,Buffer 类是用来处理二进制数据,因为太常用了,所以直接放在了全局变量里,使用的时候无需 require。 Buffer 类的实例类似于整型数组,不过缓冲区的大小在创建时确定,不能调整。Buffer 对象不同之处在于它不经 V8 的内存分配机制,Buffer 是一个 JavaScript 和 C++ 结合的模块,内存由 C++ 申请,JavaScript 分配。 关于 Buffer 内存分配相关知识不展开讨论,感兴趣同学可以看看朴老湿的书。 实例化 Buffer 在 NodeJS v6 之前都是通过调用构造函数的方式实例化...
- 下一篇
spring 注解试事物源码解析
spring 注解试事物源码解析 基于xml注解式事务入口 public class TxNamespaceHandler extends NamespaceHandlerSupport { static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager"; static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager"; static String getTransactionManagerName(Element element) { return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ? element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME); } @Override public void init() {...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果