一: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);
}
}
}