博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义类加载器深入详解
阅读量:5332 次
发布时间:2019-06-14

本文共 2646 字,大约阅读时间需要 8 分钟。

在上一次【】已经阅读了ClassLoader类的官方doc,不过只阅读了一部分,这次继续往下去读:

上面这句话是非常之重要,需要好好读一读。

至此!一字不落的将ClassLoader的官方说明给看完了,里面涉及到一些不太清楚的方法,没关系,重在对它有一个基本的认识,接下来咱们来自定义一下类加载器来实践一下:

要自定义首先肯定得去继承ClassLoader这个抽象类:

然后定义一些变量,在创建类加载器时是需要传递的信息:

但是这个构造方法还得调用一下父类的,如下:

为什么呢?先看一下这个构造的官方说明:

而再看一下getSystemClassLoader()方法的说明:

也就是这句调用父类的构造的作用就是来指定咱们自定义的类加载器的双亲是系统类加载器。

另外还需要定义一个构造方法,如下:

那这个调用父类带参数的构造又有啥含义呢?

比较容易理解,也就是这种构造就是咱们自己可以定义自己的双亲了。

接下来则根据咱们在阅读ClassLoader中自定义类的方式来继续,如下:

具体如何来加载呢?其实就是j2se读字节流了,不难理解,直接贴上代码:

好,接着再来覆写父类的另一个重要方法,也是来自于ClassLoader的javadoc说明,如下:

依葫芦画瓢:

接下来来使用一下咱们自定义的类加载器加载一下类,如下:

public class MyTest16 extends ClassLoader {    private String classLoaderName;    private final String fileExtension = ".class";//要加载的字节码文件的扩展名    public MyTest16(String classLoaderName) {        super();//将系统类加载器当作该类加载器的父加载器        this.classLoaderName = classLoaderName;    }    public MyTest16(ClassLoader parent, String classLoaderName) {        super(parent);//显示指定该类加载器的父加载器        this.classLoaderName = classLoaderName;    }    @Override    public String toString() {        return "[" + classLoaderName + "]";    }    @Override    protected Class
findClass(String className) throws ClassNotFoundException { byte[] data = this.loadClassData(className); return this.defineClass(className, data, 0, data.length); } private byte[] loadClassData(String name) { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = null; try { this.classLoaderName = this.classLoaderName.replace(".", "/"); is = new FileInputStream(new File(name + this.fileExtension)); baos = new ByteArrayOutputStream(); int ch = 0; while (-1 != (ch = is.read())) { baos.write(ch); } data = baos.toByteArray(); } catch (Exception ex) { ex.printStackTrace(); } finally { try { is.close(); baos.close(); } catch (Exception ex) { ex.printStackTrace(); } } return data; } private static void test(ClassLoader classLoader) throws Exception { Class
clazz = classLoader.loadClass("com.jvm.classloader.MyTest1"); Object object = clazz.newInstance(); System.out.println(object); } public static void main(String[] args) throws Exception { MyTest16 myTest16 = new MyTest16("loader1"); test(myTest16); }}

编译运行:

是不是很兴奋!!不过对于这个实现目前还有很多疑问,用到了findClass()、loadClassData()系统方法,具体是啥含义这里先不用纠结,在之后的学习会不断深入的,目前先对自定义类加载器有一个大体的认识,能正常的将程序跑起来达到预期既可。

转载于:https://www.cnblogs.com/webor2006/p/9095985.html

你可能感兴趣的文章
激活office 365 的启动文件
查看>>
无法根据中文查找
查看>>
[简讯]phpMyAdmin项目已迁移至GitHub
查看>>
【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)
查看>>
css文本溢出显示省略号
查看>>
git安装和简单配置
查看>>
fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
查看>>
Awesome Adb——一份超全超详细的 ADB 用法大全
查看>>
shell cat 合并文件,合并数据库sql文件
查看>>
Android 将drawable下的图片转换成bitmap、Drawable
查看>>
介绍Win7 win8 上Java环境的配置
查看>>
Linux设置环境变量的方法
查看>>
构建自己的项目管理方案
查看>>
利用pca分析fmri的生理噪声
查看>>
div水平居中且垂直居中
查看>>
epoll使用具体解释(精髓)
查看>>
AndroidArchitecture
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
大数据学习
查看>>