本帖最后由 施大勇 于 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);
- }
- }
复制代码 |