您现在的位置是:首页 > 文章详情

双亲委派模型

日期:2019-01-21点击:449

类加载流程

类加载流程,先加载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
原文链接:https://yq.aliyun.com/articles/688511
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章