一:Java虚拟机中可以安装多个类加载器,系统默认是三个主要的类加载器:
Bootstrap ExtClassLoader AppClassLoader
类加载器也是Java类。因为其他Java类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是Java类,这正是Bootstrap
二:Java虚拟机中的所有类加载器采用具有父子关系的树形结构,在实例化每个类加载器对象时,需要为其指定一个父级装载器对象或者默认采用系统累加器为其父级类加载。
父子关系及管辖范围:
BootStrap -------------------------->JRE/lib/rt.jar
ExtClassLoader------------------->JRE/lib/ext/*.jar
AppClassLoader------------------>ClassPath指定的所有jar或目录
三:类加载器委托机制
一级一级从上往下寻找,优先级从高往低加载。
当Java虚拟机需要加载一个类时,首先当前线程的类加载器去加载线程中的第一个类,通过Thread.setContextClassLoader(CloassLoader());指定。
如果类A中引用(继承等..)了类B,Java虚拟机将使用加载类A的类加载器来加载类B,还可以调用ClassLoader.loaderClass()方法来指定类加载器。
四:编写自己的类加载器
类继承ClassLoader 覆盖findClass()方法 defineClass()将字节码转换成Class对象
/*
* 自定义类加载器
*/
public class MyClassLoader extends ClassLoader{
public static void main(String[] args) throws Exception {
String srcPath = args[0];
String destPath = args[1];
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fout = new FileOutputStream(destPath);
cypher(fis, fout);
fis.close();
fout.close();
}
//重写findClass()方法
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// TODO Auto-generated method stub
return super.findClass(name);
}
// 加密方法
private static void cypher(InputStream inps, OutputStream outs)
throws Exception {
int b = -1;
while ((b = inps.read()) != -1) {
outs.write(b ^ 0xff);
}
}
}