A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 29198102shihao 中级黑马   /  2013-7-22 22:01  /  1630 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

可以自定义类加载器,并挂在类加载器树上,只需为其制定一个父类加载器,每个加载器都要有个父加载器
ClassLoader loader=new ClassLoader();使用默认的父加载器
ClassLoader loader=new ClassLoader(ClassLoader loader); 指定父加载器

5类加载器委托机制:
当源程序中用到一个A类,先派当前线程的类加载器,每个线程都有个ContextClassLoader加载器,可以为其指定,是上面三种加载器或自定义加载器,用来加载当前线程所用到的A类,如果A类又引用了B类,JVM默认还用A类的ContextClassLoader加载B类
如果先派下级加载器去加载类时,先不找,让父加载器去找,父加载器也不找,交给爷爷加载器。。。。。直到BootStrap,找到就ok,如果没找到,就下一级去找,没找到就再下一级,直到回到原加载器,没找到 报异常!原加载器不会去找下级加载器!
保证了内存中只存在一份类的字节码。而且只需加载一次,如果父加载器已经加载过就直接拿来用!!

自定义类加载器继承与ClassLoader类的MyClassLoader挂在AppClassLoader下
ClassLoader类有loadClass方法,会先去委托上级,如果找不到回到自己的话,自己调用findClass方法加载类,我们只需覆盖findClass,传入.class文件,自动返回字节码。一般不覆盖loadClass,要保证上述流程

先对.class文件加密,将输入流加密后编程输出流,放入文件中,使得其他类加载器不能加载,只有我们自定义的可以!!
class MyClassLoader{
//加密工具
1public static void sypher(InputStream input,OutputStream out){
int b=-1;
while((b=input.read())!=-1){
out.write(b^0xff);与位数全是1的进行异或运算
}}}

2mian(String args[]){
//.class文件全路径
String srcPath=args[0];
//加密后存放位置
String destinePath=args[1];
文件流默认都是从根目录开始:
FileInputStream fis=new FileInputStream(srcPath);
//获取原文件名
String name= srcPath.subString(srcPath.lastIndexOf(“/”)+1);
FileOutputStream fos=new FileOutputStream(destinePath+”/”+ “syphered”+name);
cypher(fis,fos);
fis.close();fos.close();
}
加密后的文件放入根目录下的lib下
写一个测试类Test extends Date类 放在同一包下(自己选)

对MyClassLoader传两个参数:c:/wsdd/Test  lib

输出加完密后的sypheredTest.class文件,无法直接运行,只能用自己的加载器进行解密
class MyClassLoader extends ClassLoader{
//要去加载的路径
String classdir;
//加载.class文件,返回一个Class对象,加载结果
@Override
Class findClass(String name){
//要去加载的文件路径
String path=classdir+”/”+name+”.class”;
//先解密
FileInputStream fis=new FileInputStream(path);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
//再调一次就是解密,放入baos流里,缓存下
cypher(fis,baos);
fis.close();
Byte[]b=baos.getBytes();
//将字节数组生成Class对象,利用ClassLoader的defineClass方法
return defineClass(b,0,b.length);

//覆盖方法,自动生成
return super. findClass(name);
}
public MyClassLoader(){}
//传入要去加载的路径
public MyClassLoader(String classdir){
this.classdir=classdir;
}
}

main(){
//传递加密后的.class文件路径,由自己的加载器加载
Class class=new MyClassLoader(“lib”).loadClass(“sypheredTest”);
//就可以创建对象
sypheredTest s=class.newInstance();
此时会报错,因为编译器检查到这一行,就会加载sypheredTest,但是乱码有问题,不能通过
}

评分

参与人数 1技术分 +1 收起 理由
特殊服务 + 1

查看全部评分

1 个回复

正序浏览
您需要登录后才可以回帖 登录 | 加入黑马