------- android培训、java培训、期待与您交流! ----------
类加载器及其委托机制的深入分析
类加载器是加载类的工具.
Java虚拟机中可以安装多个类加载器,系统有默认的三个主要类加载器.每个类负责加载不同目录下的类。
这3个类加载器分别是BootStrap,ExtClassLoader,AppClassLoader这3个,其中BootStrap不是java类,是C++编写的,是java虚拟机自带的。
这3个类加载器分别加载JRE/lib/rt.jar||JRE/lib/ext/*.jar||classpath目录下的jar或目录。
类加载器也是Java类,因为其他是java类的加载器本身也要被加载器加载,所以才需要BootStrap这个类加载器来加载第一个类
类加载器的委托机制
每个类加载器加载类时,都先去委托给其上级类加载器,当所有的上积累加载器都没有加载到类时,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不会再找发起者的子类,因为没有getChild方法,即使有,那么当有多个子类的时候,不知道该找哪一个
如果自定义加载器的时候必须继承一个类:ClassLoader
public classClassLoaderTest {
public static void main(String[] args) {
//输出ClassLoaderTest的类加载器
System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());
//输出System的类加载器
System.out.println(System.class.getClassLoader());
}
}
编写一个自己的类加载器
步骤:
1,自定义加载器必须继承ClassLoader
2,loadClass方法为父类方法(去找父类加载器)findClass方法3,defineClass(将得到的class文件转换成字节码)
packagecn.itcast.day2;
importjava.io.ByteArrayOutputStream;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.InputStream;
importjava.io.OutputStream;
public classMyClassLoader extends ClassLoader{
//加密部分
public staticvoid main(String[] args) throws Exception {
// TODO Auto-generated method stub
String srcPath = args[0];//目标目录
String destDir = args[1];//源目录
FileInputStream fis = new FileInputStream(srcPath);
String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
String destPath = destDir + "\\" + destFileName;
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
private staticvoid cypher(InputStream ips ,OutputStream ops) throws Exception{
int b = -1;
while((b=ips.read())!=-1){
ops.write(b ^ 0xff);
}
}
private StringclassDir;
//解密部分
@Override
protectedClass<?> findClass(String name) throws ClassNotFoundException {
// TODO Auto-generated method stub
String classFileName = classDir + "\\" + name.substring(name.lastIndexOf('.')+1) +".class";
try {
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cypher(fis,bos);
fis.close();
System.out.println("aaa");
byte[] bytes = bos.toByteArray();
return defineClass(bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
publicMyClassLoader(){
}
publicMyClassLoader(String classDir){
this.classDir = classDir;
}
}
packagecn.itcast.day2;
//做加密用的,对此进行加密处理
//加密处理后放的class入到itcastlib文件夹下
importjava.util.Date;
public classClassLoaderAttachment extends Date {
public StringtoString()
{
return "hello,itcast";
}
}
------- android培训、java培训、期待与您交流! ----------