JVM中自定义类加载器的编写(示例)
博主是一个中大型的公司的java开发,工作了两年,但是感觉自己的知识贮备量还是不够,于是开始了解JVM的底层代码,通过了解源码来查看整个类加载的机制
接下来进入正题,自己编写JVM自定义的类加载的时候,要搞懂JVM都有哪几个类加载器,JVM总共有
四种类加载器:引导类加载器(bootstrapClassLoader)、扩展类加载器(extClassLoader)、应用类加载器(appClassLoader)、自定义类加载器。
相信各位亲们,能够来看自定义类加载器的编写,应该已经了解前三种类加载器了,这里就不再过多的去介绍,直接说一下自定义的流程,该类加载器的父加载器是appClassLoader,具体实现过程跟其相同,加载器最重要的部分就是创建加载器去调用它的loadClass方法,去进行类加载的操作
public class MyClassLoaderTest {
public static class MyClassLoader extends ClassLoader {
private String classPath;
public MyClassLoader(String classPath) {
this.classPath = classPath;
}
private byte[] loadByte(String className) throws IOException {
className = className.replace("\\.", "/");
FileInputStream fileInputStream = new FileInputStream(classPath +
"/" + className + ".class");
int len = fileInputStream.available();
byte[] data = new byte[len];
fileInputStream.read(data);
fileInputStream.close();
return data;
}
protected Class<?> findClass(String name){
byte[] data = new byte[0];
try {
data = loadByte(name);
} catch (IOException e) {
e.printStackTrace();
}
return defineClass(name, data, 0, data.length);
}
public static void main(String[] args) {
MyClassLoader myClassLoader = new MyClassLoader("D:/test");
Class myClass = myClassLoader.loadClass("com.gp.jvm.User1");
Object object = myClass.newInstance();
Method method = myClass.getDeclaredMethod("sout", null);
method.invoke(object, null);
System.out.println(myClass.getClassLoader().getClass().getName());
}
}
}
————————————————————————————————————————————
上面是我自己随便写的一个自定义的类加载器,它是符合双亲委派机制的自定义类加载器,非常强烈建议大家自己去看一下ClassLoader的源码,我们首先要去写一个构造方法来指定文件地址,我们需要去读取我们的目标文件,并且获取二进制字节码,重写findClass方法,去寻找我们指定的类,进行赋值,使用defineClass去定义Class对象,接下来就是去调用我们的核心方法loadClass(),一个自己写的自定义类加载器就写好了;
调用核心方法的时候,可以在源码看到,它在该方法里面会调用findClass方法去寻找我们的类,并且会根据双亲委派机制去向上寻找我们的父加载器,注意!!!!父加载器不等同于父类,所有类加载器的父类都是ClassLoader;
如果父类没有加载过那么久一直往上传递,如果都没有进行加载过,那么我们自定义的加载器就开始自己加载我们指定的类;
以上描述可能会不太清晰,请各位大牛轻喷,写这篇文章的目的是为了检测自己是否对于自定义类加载器的了解程度,也希望各位能够在评论区批评我的不足,接下来我会继续加载更多我正在学习的JVM知识。