黑马程序员技术交流社区

标题: ClassLoader的defineClass方法中的形参name的含义 [打印本页]

作者: 张洪慊    时间: 2013-7-26 19:49
标题: ClassLoader的defineClass方法中的形参name的含义
本帖最后由 张洪慊 于 2013-7-26 21:11 编辑

关于自定义类加载器与加密解密过程中关于defineClass问题:

1.先自定义了一个类(EncryptClass.java)用于加密与解密测试:
  1. package com.itheima.day5;

  2. import java.util.Date;

  3. public class EncryptClass extends Date {
  4.   @Override
  5.   public String toString(){
  6.           return "success";
  7.   }
  8. }
复制代码
2.按高新视频上的简单的^0xff进行加密与解密,加密后的EncryptClass.class放在myEncryptClass文件夹下,在运行前反复确认已删除掉 bin/com/itheima/day5 下的EncryptClass.class文件.
  1. <p>package com.itheima.day5;

  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.io.File;
  8. public class CustomClassLoader extends ClassLoader{

  9.         /**
  10.          * @param args;
  11.          */
  12.         public static void main(String[] args)throws Exception {
  13.                 // TODO Auto-generated method stub
  14.             //args[0]作为源路径,args[1]作为目的路径
  15.             //我把加密和解密在同一个main中执行,在运行加密后注释掉 防止在删除bin下的EncryptClass后,由于找不到文件会报
  16.                    //FileNotFoundException
  17.            /* File file=new File(args[0]);
  18.             FileInputStream fis=new FileInputStream(file);
  19.             FileOutputStream fos=new FileOutputStream(args[1]+"\\\\"+file.getName());
  20.             encryptClass(fis,fos);
  21.             fis.close();
  22.             fos.close();
  23.            */
  24.            Class cls=new CustomClassLoader("myEncryptClass").findClass("EncryptClass");
  25.            System.out.println(cls.newInstance().toString());
  26.            
  27.         }
  28.         
  29.         //简单加密
  30.         public static void encryptClass(InputStream in,OutputStream os)throws IOException{
  31.                 int aByte=0;
  32.                 while((aByte=in.read())!=-1){
  33.                        os.write(aByte^0xff);//最简单的加密->.class中的每个字节^255
  34.                 }
  35.     }
  36.         
  37.         
  38.         private String  classDir;
  39.         
  40.         public CustomClassLoader(String classDir) {
  41.                 super();
  42.                 this.classDir = classDir;
  43.         }

  44.         @Override</p><p>public Class<?> findClass(String name)throws ClassNotFoundException{
  45.                 String path=classDir+"\\"+name+".class";
  46.                 File file=new File(path);
  47.             FileInputStream fis=null;
  48.                 byte[] byteArr=new byte[1024];
  49.             int aByte=0;
  50.             int pointer=0;
  51.                 try{
  52.                     fis=new FileInputStream(file.getAbsolutePath());
  53.                
  54.                 while((aByte=fis.read())!=-1)
  55.                          byteArr[pointer++]=(byte)(aByte ^ 255);//解密
  56.              }
  57.             catch(Exception e){
  58.               e.printStackTrace();
  59.             }
  60.             finally{
  61.               if(fis!=null)        
  62.                       try{
  63.                               fis.close();
  64.                       }
  65.                  catch(Exception e){
  66.                      e.printStackTrace();
  67.                  }
  68.             }
  69.           return defineClass(name,byteArr,0,pointer);
  70.         }
  71.         
  72. }
  73. </p>
复制代码
defineClass(name,byteArr,0,pointer);会报    (该包下该类已删除)

视频中用的过时的没有name形参.
但是如果我defineClass(null,byteArr,0,pointer)成功:


那么这个name到底代表什么含义?是不是要查找的类?还是根据字节码新生成的类?
在很久以前有一个这样的问题,我都看了,没有彻底解决http://bbs.itheima.com/thread-13476-1-1.html
麻烦各位同学了.


作者: 王靖远    时间: 2013-7-26 20:06
我感觉这个传入的类名。例如:com.itheima.day5.EncryptClass 不知道是不是这个意思,你可以试试
作者: 张洪慊    时间: 2013-7-26 21:09
本帖最后由 张洪慊 于 2013-7-26 21:19 编辑

受王靖远同学的启发:
我忽略了一点:
EncryptClass.java是在com/itheima/day5包下创建的->那么在其.class中包含有包名信息->在defineClass(name,byteArr,0,pointer);->defineClass会以byteArr中的字节数据进行解析->我传的name和它解析的不一致->NoClassDefFoundError
这时可以把name换成com.itheima.day5.EncryptClass测试一下, 就像王靖远同学说的一样.
而传入null也可以成功意思就是说:"哥们我不知道这个完整类名,你根据.class文件中的字节解析一下吧,这时候不在比对你指定的name"
有兴趣的同学可以用无名包下的类测试下,我测试可以成功的.
好吧,更狠点:






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2