一,如何自定义classLoader?
需要使用加载器的loadClass方法:ClassLoader().loadClass
查看loadClass方法源码
首先检查加载,调用父5加载器开始双亲委派机制,
如果没有加载到,就调用findClass方式
打开发现是抛出了异常,那么如何自定义自己的类加载器,就只能重写这个方法来完成。
我们知道ClassLoader是所有加载器的父类,根据
Launcher找到ExtClassLoader ,然后根据继承关系找到直接ClassLoader的子类SecureClassLoader ,查看其findClass方法实现;但由于SecureClassLoader没有对findClass实现,最后发现在URLClassLoader 中找到了对应的实现。
1,找到对应的文件,转为二进制流;
2,交给父类的defineClass加载到内存中;
二,自定义ClassLoader
1,准备一个被加载的类
放在非项目下,我的是在D盘下
新建一个HelloWorld.txt
以utf-8无BOM格式转为.JAVA文件,使用 javac编译城class
2,自定义ClassLoader并findClass方法
package com.example.demo.jvm.classLoader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test2_MyClassLoad extends ClassLoader {
public static void main(String argv[]) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Test2_MyClassLoad test2_myClassLoad = new Test2_MyClassLoad();
Class<?> c = test2_myClassLoad.loadClass("HelloWorld");
//输出HelloWorld的加载器
System.out.println(c.newInstance().getClass().getClassLoader());
//输出自定义加载器的加载器
System.out.println(test2_myClassLoad.getClass().getClassLoader());
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadByte("D:/".concat(name).concat(".class"));
return defineClass(name,bytes,0,bytes.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return super.findClass(name);
}
private byte[] loadByte(String path) throws IOException {
File file = new File(path);
FileInputStream fi = new FileInputStream(file);
int len = fi.available();
byte[] b = new byte[len];
fi.read(b);
return b;
}
}
console:
Hello World !
com.example.demo.jvm.classLoader.Test2_MyClassLoad@19469ea2
sun.misc.Launcher$AppClassLoader@18b4aac2