当然我们还要先做一个操作就是,将ClassLoaderAttachment.class加密后的文件存起来,也就是在main方法中执行的,这里我是在项目中新建一个class_temp文件夹用来皴法加密后的class文件:

同时采用的是参数的形式来进行赋值的,所以在运行的MyClassLoader的时候要进行输入参数的配置:右击MyClassLoader->run as -> run configurations

第一个参数是ClassLoaderAttachment.class文件的源路径,第二个参数是加密后存放的目录,运行MyClassLoader之后,刷新class_temp文件夹,出现了ClassLoaderAttachment.class,这个是加密后的class文件。
< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+z8LD5sC0v7TSu8/CsuLK1MDgo7o8L3A+CjxwPjxwcmUgY2xhc3M9"brush:java;">package com.loadclass.demo; import java.util.Date; import java.util.List; /** * 测试类 * @author Administrator */ public class ClassLoaderTest { @SuppressWarnings("rawtypes") public static void main(String[] args){ //输出ClassLoaderText的类加载器名称 System.out.println("ClassLoaderText类的加载器的名称:"+ClassLoaderTest.class.getClassLoader().getClass().getName()); System.out.println("System类的加载器的名称:"+System.class.getClassLoader()); System.out.println("List类的加载器的名称:"+List.class.getClassLoader()); System.out.println("默认的类加载器:"+ClassLoaderTest.class.getClassLoader().getSystemClassLoader()); ClassLoader cl = ClassLoaderTest.class.getClassLoader(); while(cl != null){ System.out.print(cl.getClass().getName()+"->"); cl = cl.getParent(); } System.out.println(cl); try { Class classDate = new MyClassLoader("class_temp").loadClass("ClassLoaderAttachment"); Date date = (Date) classDate.newInstance(); //输出ClassLoaderAttachment类的加载器名称 System.out.println("ClassLoader:"+date.getClass().getClassLoader().getClass().getName()); System.out.println(date); } catch (Exception e1) { e1.printStackTrace(); } } } 运行ClassLoaderTest类,运行结果如下:

ClassLoaderAttachment类的加载器是我们自己定义的类加载器MyClassLoader,同时也输出了Hello ClassLoader字段
到此不要以为结束了,这里还有很多的问题呀,看一下问题的结果是没有问题,但是这里面还有很多的东西需要去理解的,首先来看一下,按照我们之前说的类加载机制,应该是先交给父级的类加载器,AppClassLoader->ExtClassLoader->BootStrap,ExtClassLoader和BootStrap没有找到ClassLoaderAttach.class,但是AppClassLoader类加载器应该能找到呀,可以为什么也没有找到呢?这时因为loadClass方法在使用系统类加载器的时候需要传递全称(包括包名),我们传递ClassLoaderAttachment的话,AppClassLoader也是没有找到这个ClassLoaderAttachment,所以还是MyClassLoader处理了,不信的话可以试一下:
现在将
Class classDate = new MyClassLoader("class_temp").loadClass("ClassLoaderAttachment");改成:
Class classDate = new MyClassLoader("class_temp").loadClass("com.loadclass.demo.ClassLoaderAttachment");结果运行:

这时候的加载器是AppClassLoader了,所以要注意loadClass方法传递的参数
到这里我们貌似还没有测试到我们加密后的class文件,我们现在将工程目录中的ClassLoaderAttachment.class删除,将class_temp中加密的ClassLoaderAttachment.class拷贝过去,然后再运行:

这时候就会报错了,不合适的魔数错误(class文件的前六个字节是个魔数用来标识class文件的),这时候就对了,因为ClassLoaderAttachment.class使我们加密后的class文件,AppClassLoader是不认识的,所以报这个错误了,只有用我们自己定义的类加载器来进行解密才可以正确的