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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 潘廖明 于 2013-5-16 00:42 编辑

package com.my.day02;

import java.util.Date;

public class ClassLoadTest
{

        /**
         * @param args
         */
        public static void main(String[] args) throws Exception
        {
                // 先实例化我们的类加载器,然后调用loaderClass("被加载的类的名字")获得该类的字节码,然后实例化该对象。

                Class clazz = new MyClassLoader("itcast").findClass("ClassLoaderAttachment");
        

        Date date = (Date) clazz.newInstance();
        //        ClassLoaderAttachment date = (ClassLoaderAttachment) //clazz.newInstance();为什么是错的?上面那段代码不是已经把类加载
       //到内存中了?要是ClassLoaderAttachment没有父类Date,按这个意思//走就没办法调用了。

                System.out.println(date.toString());
        }
}
  1. package com.my.day02;

  2. import java.util.Date;

  3. /*
  4. * 准备要被加载的类
  5. */
  6. public class ClassLoaderAttachment extends Date
  7. {

  8.         @Override
  9.         public String toString()
  10.         {

  11.                 return "hello,itcase";
  12.         }

  13. }
复制代码
  1. package com.my.day02;

  2. import java.io.ByteArrayOutputStream;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;

  9. public class MyClassLoader extends ClassLoader
  10. {

  11.         /*
  12.          * 自定义一个类加载器: 思路:一、制作一个加密器
  13.          * 1,从调用类的main方法上面接收收入流的路径(指的是编译好的二进制数据),还有一个输出流的路径(指的是加密二进制数据之后存储的文件路径)
  14.          * 2,定义一个输入流与输出流,然后把接收进来的两个路径字符分别传入他们的构造方法,给他们初始化
  15.          * 3,定义一个cypher()用于加密的函数,接收输入流与输出流作为他们的形参,加密算法:把输入流的二进制数据,经过异或0xff然后存储输出流对应的文件中。
  16.          * 二、具体实现类加载器步骤 1、让MyClassLoader去继承ClassLoader类
  17.          * 2、定义一个构造方法,实现把要被解码的ClassLoaderAttachment.class的目录的名字作为参数。
  18.          * 3、复写findClass()实现解密。工作如下: String
  19.          * classFileName=classDir+"\\"+name+".class"; FileInputStream fis=new
  20.          * FileInputStream(classFileName); ByteArrayOutPutStream bos=new
  21.          * ByteArrayOutPutStream(); cypher(fis,bos); fis.close; Byte []
  22.          * bytes=bos.toByteArray(); return findClass(bytes,0,bytes.length);
  23.          */
  24.         public static void main(String[] args) throws Exception
  25.         {
  26.                 aploxyCypher(args);

  27.         }

  28.         @Override
  29.         protected Class<?> findClass(String name) throws ClassNotFoundException
  30.         {
  31.                 String classFileName = classDir + "\\" + name + ".class";
  32.                 try
  33.                 {
  34.                         FileInputStream fis = new FileInputStream(classFileName);
  35.                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  36.                         cypher(fis, bos);
  37.                         byte[] bytes = bos.toByteArray();
  38.                         return defineClass(bytes, 0, bytes.length);

  39.                 } catch (Exception e)
  40.                 {
  41.                         // throw new RuntimeException("解密出错!");
  42.                 }

  43.                 return super.findClass(name);
  44.         }

  45.         private String classDir;

  46.         public MyClassLoader(String classDir)
  47.         {
  48.                 this.classDir = classDir;
  49.         }

  50.         public MyClassLoader()
  51.         {
  52.                 // TODO Auto-generated constructor stub
  53.         }

  54.         /**
  55.          * 加密的具体业务
  56.          *
  57.          * @param args
  58.          * @throws FileNotFoundException
  59.          * @throws IOException
  60.          */
  61.         private static void aploxyCypher(String[] args) throws FileNotFoundException, IOException
  62.         {
  63.                 String srcPath = args[0];
  64.                 String destDir = args[1];
  65.                 FileInputStream is = new FileInputStream(srcPath);
  66.                 String fileName = srcPath.substring(srcPath.lastIndexOf('\\'));
  67.                 String destPath = destDir + "\\" + fileName;
  68.                 FileOutputStream os = new FileOutputStream(destPath);
  69.                 cypher(is, os);
  70.         }

  71.         /**
  72.          * 加密函数
  73.          *
  74.          * @param is
  75.          * @param os
  76.          * @throws IOException
  77.          */
  78.         private static void cypher(InputStream is, OutputStream os) throws IOException
  79.         {
  80.                 int b = -1;
  81.                 while ((b = is.read()) != -1)
  82.                 {
  83.                         os.write(b ^ 0xff);
  84.                 }

  85.         }

  86. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

5 个回复

倒序浏览
好长的题目啊,你要问啥啊
回复 使用道具 举报
首先楼主没有分清楚java程序的分编译时期和运行时期,如果弄明白了这个问题就迎刃而解了。
ClassLoaderAttachment date = (ClassLoaderAttachment)clazz.newInstance(); 这里出现的错误是编译时错误。因为在编译的时候,java只是检查语法错误,这个时候ClassLoaderAttachment.class文件编译器认为还没有,所以不能用。
回复 使用道具 举报
赵崇友 发表于 2013-5-15 09:36
首先楼主没有分清楚java程序的分编译时期和运行时期,如果弄明白了这个问题就迎刃而解了。
ClassLoaderAtta ...

那为什么只看见他的父类(Date),要是没有父类Date,你调用clazz.nwInstance()不就是不行了?
回复 使用道具 举报
Date类是java类库中的呀,你上面已经通过Import导入了这个类了。如果你把ClassLoaderAttachment类也导入的话,这里就不会报错了。而这样做就和程序本来要实现的目标就违背了。这个程序的代码就是为了不让APPClassLoader加载,而使用自己定义的类加载器。
clazz.newInstance 是根据字节码创建的对象和Date没有关系的。
回复 使用道具 举报
赵崇友 发表于 2013-5-15 14:24
Date类是java类库中的呀,你上面已经通过Import导入了这个类了。如果你把ClassLoaderAttachment类也导入的 ...

懂了傻了我!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马