如何自定义加载器?
1.创建一个自定义加载器类 继承 ClassLoader
类
2.重写 findClass 方法。 主要是实现从那个路径读取 jar包或者.class文件,将读取到的文件用字节数组来存储,然后可以使用父类的 defineClass
来转换成字节码。
如果想破坏双亲委派的话,就重写 loadClass 方法, 否则不用重写
注意:
1.ClassLoader提供的 protected final Class<?> defineClass(String name, byte[] b, int off, int len) 是用来将字节数组转换成字节码文件的,传入参数 是 (类名,字节数组数据,字节数组读取的开始下标,字节数组的长度)
示例:读取某文件的下的某class文件
创建一个名为MyClassLoader的类加载器:
import java.io.*;
public class MyClassLoader extends ClassLoader{
String path ;
MyClassLoader(String dir){
this.path = dir ;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
this.path = this.path + name +".class";
File f = new File(path);
InputStream in = new FileInputStream(f);
byte [] bys = new byte[ (int)f.length() ];
int len = 0;
while( (len = in.read(bys) )!= -1 ){
}
// byte[] -> .class
return defineClass(name,bys,0,bys.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return super.findClass(name);
}
}
测试:
在如下目录,生成一个Hello.class字节码文件
Hello.java:
public class Hello {
public void sayHello(){
System.out.println("Hello World!");
}
}
测试类:
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
MyClassLoader my = new MyClassLoader("D:\\test\\jvmtest\\");
Class<?> c1 = my.loadClass("Hello");
Object o = c1.newInstance();
Method d = c1.getMethod("sayHello",null);
d.invoke(o);
}
}
运行测试类: