黑马程序员技术交流社区
标题:
自定义类加载器的加载过程求详解
[打印本页]
作者:
施大勇
时间:
2013-9-13 12:03
标题:
自定义类加载器的加载过程求详解
本帖最后由 施大勇 于 2013-9-28 15:36 编辑
在自定义类的加载器中,我将一个Student.class类加密后放在了test文件夹中,但是原Student.class文件在原位置是不变的,用自定义的类加载器加载,按照委托代理机制不是还由父类加载器加载吗?
但是我看好像没有去找父类加载器加载,直接由自定义的加载器在指定的文件中加载了,求解自定义类的加载器是如何找到文件并加载的。
下面是代码:
package load2;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
//类加载器的工作原理:ClassLoader类中的loadClass()方法用于加载类。
//loadClass()如何工作的呢,按照委托代理机制,如果父类加载器没有加载成功,用findClass()来找类并加载。
//而findClass()直接调用defineClass()返回类的二进制字节码。
//loadClass()-->findClass()-->defineClass()
public class MyClassLoader extends ClassLoader{
public static void main(String[] args) throws Exception {
//为指定的类进行加密。
String srcPath=args[0];
String srcName=srcPath.substring(srcPath.lastIndexOf("\\"));
String descDir=args[1];
String descPath=descDir+"\\"+srcName;
FileInputStream fis=new FileInputStream(srcPath);
FileOutputStream fos=new FileOutputStream(descPath);
cypher(fis,fos);
fis.close();
fos.close();
}
//加密函数。
public static void cypher(InputStream is,OutputStream os) throws Exception{
int b=0;
while ((b=is.read())!=-1){
os.write(b^0xff);
}
}
//自定义加载器通过构造方法指定要加载的类所在的目录。
private String classPath;
public MyClassLoader(){}
public MyClassLoader(String className){
this.classPath=className;
}
@Override
//类加载器加载的过程通过loadClass()找findClass()到defineClass();
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className=classPath+"\\"+name+".class";
try {
FileInputStream fis=new FileInputStream(className);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
cypher(fis,bos);
byte[]bytes=bos.toByteArray();
System.out.println("****************************");
return defineClass(bytes, 0, bytes.length);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
package load2;
public class TestPerson {
public static void main(String[] args) throws Exception {
//System.out.println(new Student().toString());
Class clazz=new MyClassLoader("test").loadClass("Student");//这里并没有去找父类加载器吧?因为在原目录下的文件并没有删除,
System.out.println("-------------------------");//直接找的指定目录文件。
Person p=(Person)clazz.newInstance();
System.out.println("-------------------------");
System.out.println(p);
}
}
复制代码
作者:
第一印象
时间:
2013-9-13 17:22
同样的疑问,我也测试了一下,不管是放在类路径下,还是将类打成jar包放在ext下,如果我用自己的类加载器去加载我任意目录下的文件(包括类路径下),都不会去找父类的加载器,跟老张说的有点冲突,因为我只重写了findClass方法,所以,loadClass方法里面找父类的流程代码是没有被覆盖的,照理说也是会去找父类的,不知道为什么用自己的类加载器后,就没去找父类了
作者:
施大勇
时间:
2013-9-14 15:25
第一印象 发表于 2013-9-13 17:22
同样的疑问,我也测试了一下,不管是放在类路径下,还是将类打成jar包放在ext下,如果我用自己的类加载器去 ...
同样的问题,我现在还是不懂,你要是明白了一定千诉我啊
作者:
施大勇
时间:
2013-9-14 15:26
顶顶贴,论坛的大侠们快来帮帮忙啊,求解
作者:
黄文伯
时间:
2013-9-14 19:59
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
作者:
yting_xmei1129
时间:
2013-9-20 14:53
1.看下JDK目录是否正确,我也出了这个问题,是不是用的默认的JDK
2.以前被你Export的JAR FILE 是否删除掉了,如果没删除的话会执行以前的字节码,修改之后的不会执行
3.包名的问题
4.出错之后记得重启一下MyEclipse(我用的是MyEclopse)
我也看了那个视频并做了实验,中间也出了几个错误,后面还是解决了,希望帮到你们、、、
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2