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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 施大勇 中级黑马   /  2013-9-13 12:03  /  2053 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 施大勇 于 2013-9-28 15:36 编辑
  1. 在自定义类的加载器中,我将一个Student.class类加密后放在了test文件夹中,但是原Student.class文件在原位置是不变的,用自定义的类加载器加载,按照委托代理机制不是还由父类加载器加载吗?
  2. 但是我看好像没有去找父类加载器加载,直接由自定义的加载器在指定的文件中加载了,求解自定义类的加载器是如何找到文件并加载的。
  3. 下面是代码:
  4. package load2;
  5. import java.io.ByteArrayOutputStream;
  6. import java.io.FileInputStream;
  7. import java.io.FileOutputStream;
  8. import java.io.InputStream;
  9. import java.io.OutputStream;
  10. //类加载器的工作原理:ClassLoader类中的loadClass()方法用于加载类。
  11. //loadClass()如何工作的呢,按照委托代理机制,如果父类加载器没有加载成功,用findClass()来找类并加载。
  12. //而findClass()直接调用defineClass()返回类的二进制字节码。
  13. //loadClass()-->findClass()-->defineClass()
  14. public class MyClassLoader extends ClassLoader{

  15. public static void main(String[] args) throws Exception {
  16.   //为指定的类进行加密。
  17.   String srcPath=args[0];
  18.   String srcName=srcPath.substring(srcPath.lastIndexOf("\\"));
  19.   String descDir=args[1];
  20.   String descPath=descDir+"\\"+srcName;
  21.   FileInputStream fis=new FileInputStream(srcPath);
  22.   FileOutputStream fos=new FileOutputStream(descPath);
  23.   cypher(fis,fos);
  24.   fis.close();
  25.   fos.close();
  26. }
  27. //加密函数。
  28. public static void cypher(InputStream is,OutputStream os) throws Exception{
  29.   int b=0;
  30.   while ((b=is.read())!=-1){
  31.    os.write(b^0xff);
  32.   }
  33. }
  34. //自定义加载器通过构造方法指定要加载的类所在的目录。
  35. private String classPath;
  36. public MyClassLoader(){}
  37. public MyClassLoader(String className){
  38.   this.classPath=className;
  39. }
  40. @Override
  41. //类加载器加载的过程通过loadClass()找findClass()到defineClass();
  42. protected Class<?> findClass(String name) throws ClassNotFoundException {
  43.   String className=classPath+"\\"+name+".class";
  44.   try {
  45.    FileInputStream fis=new FileInputStream(className);
  46.    ByteArrayOutputStream bos=new ByteArrayOutputStream();
  47.    cypher(fis,bos);
  48.    byte[]bytes=bos.toByteArray();
  49.    System.out.println("****************************");
  50.    return defineClass(bytes, 0, bytes.length);
  51.   } catch (Exception e) {
  52.    // TODO Auto-generated catch block
  53.    e.printStackTrace();
  54.   }
  55.   return null;
  56. }

  57. }
  58. package load2;
  59. public class TestPerson {
  60. public static void main(String[] args) throws Exception {
  61.   //System.out.println(new Student().toString());
  62.   Class clazz=new MyClassLoader("test").loadClass("Student");//这里并没有去找父类加载器吧?因为在原目录下的文件并没有删除,
  63. System.out.println("-------------------------");//直接找的指定目录文件。

  64.   Person p=(Person)clazz.newInstance();
  65.   System.out.println("-------------------------");
  66.   System.out.println(p);
  67. }
  68. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
潘才新 + 1

查看全部评分

5 个回复

倒序浏览
同样的疑问,我也测试了一下,不管是放在类路径下,还是将类打成jar包放在ext下,如果我用自己的类加载器去加载我任意目录下的文件(包括类路径下),都不会去找父类的加载器,跟老张说的有点冲突,因为我只重写了findClass方法,所以,loadClass方法里面找父类的流程代码是没有被覆盖的,照理说也是会去找父类的,不知道为什么用自己的类加载器后,就没去找父类了
回复 使用道具 举报
第一印象 发表于 2013-9-13 17:22
同样的疑问,我也测试了一下,不管是放在类路径下,还是将类打成jar包放在ext下,如果我用自己的类加载器去 ...

同样的问题,我现在还是不懂,你要是明白了一定千诉我啊
回复 使用道具 举报
顶顶贴,论坛的大侠们快来帮帮忙啊,求解
回复 使用道具 举报
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
回复 使用道具 举报
1.看下JDK目录是否正确,我也出了这个问题,是不是用的默认的JDK
2.以前被你Export的JAR FILE 是否删除掉了,如果没删除的话会执行以前的字节码,修改之后的不会执行
3.包名的问题
4.出错之后记得重启一下MyEclipse(我用的是MyEclopse)
我也看了那个视频并做了实验,中间也出了几个错误,后面还是解决了,希望帮到你们、、、
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马