我们知道,类加载器主要工作在类装载的加载阶段,它通过loadClass()方法,将class文件字节码,加载到内存中,并将静态数据转换成运行时数据区中方法区中的类型数据,在运行时,数据区堆中生成一个代表这个类的java.lang.class对象,作为方法区类数据的访问入口。
那么,如果实现一个自定义的类加载器呢?
实现一个自定义类加载器,离不开以下两个关键函数:
Protected Class<?> findClass(String name) throws ClassNotFoundException{
Throw new ClassNotFoundException(name);
}
该函数用来寻找class文件,包括怎么读进二进制流,并且去对它做处理,进而给它返回一个class对象。
Protected final Class<?> defineClass(byte[] b,int off,int len) throws ClassFormatError{
return defineClass(null,b,off,len,null);
}
定义一个类,接收的参数是一个byte[]字节码类型的数组形式,接收到字节流后,我们就可以对它进行定义了,然后返回一个class。
实例如下:
注意:在在加载之前,要先将被加载类编译成class文件。
定义一个被加载类
public class Paul{
static {
System.out.println(hello + "Paul");
}
}
定义类加载器
public class MyClassLoader extends ClassLoader{
private String path;
private String classLoaderName;
public MyClassLoader(String path, String classLoaderName){
this.path = path;
this.classLoaderName = classLoaderName;
}
/*
*寻找类文件
*/
@Override
public Class findClass(String name){
byte[] b = loadClassData(name);
//defineClass()是final类型的,已默认实现好
return defineClass(name, b, 0, b.length);
}
/*
*加载类文件
*/
private byte[] loadClassData(String name){
name = path + name + ".class";
inputStream in = null;
//byte[]类型
ByteArrayOutputStream out = null;
try{
in = new FileInputStream(new File(name));
out = new ByteArrayOutputStream();
int i = 0;
while((i = in.read()) != -1){
out.write(i);
}
}catch(Exception e){
e.printStackTrace();
} finally{
try{
out.close();
in.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
测试类
public class ClassLoaderChecker{
public static void main(String[] args){
MyClassLoader m new MyClassLoader("C:/Users/admin/Desktop/test/Paul/","myClassLoader");
Class c = m.loadClass("Paul");
System.out.println(c.getClassLoader());
c.newInstance();
}
}
本博客属纯手机输入,如有错误,欢迎指正。