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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周洋 黑马帝   /  2012-3-28 00:49  /  1554 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

怎么实现的 自定义类加载器啊

2 个回复

倒序浏览
package com.classloader;
/**
* 一、ClassLoader加载类的顺序
* 1.调用 findLoadedClass(String) 来检查是否已经加载类。
* 2.在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。
* 3.调用 findClass(String) 方法查找类。
* 二、实现自己的类加载器
* 1.获取类的class文件的字节数组
* 2.将字节数组转换为Class类的实例
* @author Administrator
*
*/
public class ClassLoaderTest {
        public static void main(String[] args)throws InstantiationException, IllegalAccessException, ClassNotFoundException  {
                                  //新建一个类加载器
                MyClassLoader cl = new MyClassLoader("myClassLoader");
                                   //加载类,得到Class对象
                Class<?> clazz = cl.loadClass("com.classloader.Animal");
                                //得到类的实例
                 Animal animal=(Animal) clazz.newInstance();
                 animal.say();
        }
       

}


package com.classloader;

public class Animal {
        public void say(){
                System.out.println("hello world!");
        }

}

package com.classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

public class MyClassLoader extends ClassLoader {

        // 类加载器的名称
        private String name;
        // 类存放路径
        private String path = "G:\\MyWorkspaces\\Test\\src";

        MyClassLoader(String name) {
                this.name = name;
        }

        MyClassLoader(ClassLoader parent, String name) {
                super(parent);
                this.name = name;
        }

        // 重写findClass方法
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {

                byte[] data = loadClassData(name);
                return this.defineClass(name, data, 0, data.length);
        }

        public byte[] loadClassData(String name) {
                try {
                        name = name.replace(".", "//");

                        FileInputStream is = new FileInputStream(new File(path + name
                                        + ".class"));
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        int b = 0;
                        while ((b = is.read()) != -1) {
                                baos.write(b);
                        }
                        return baos.toByteArray();
                } catch (Exception e) {

                        e.printStackTrace();
                }
                return null;

        }

}


评分

参与人数 1技术分 +2 收起 理由
职业规划-刘倩老师 + 2 赞一个!

查看全部评分

回复 使用道具 举报
系统类加载器是自定义类加载器的父加载器。若想实现自定义类加载器,需实现java.lang.ClassLoader类。
  1. import java.io.ByteArrayOutputStream;   
  2. import java.io.File;   
  3. import java.io.FileInputStream;   
  4. import java.io.InputStream;   
  5.   
  6. public class MyClassLoader extends ClassLoader{   
  7.     private String name;//类加载器的名字   
  8.     private String path = "F:\\";//加载类的路径   
  9.     private static final String fileType = ".class";//文件的扩展名   
  10.     public MyClassLoader(String name){   
  11.         super();//显式地调用父类构造器,将该加载器的父加载器设置为默认的系统加载器   
  12.         this.name = name;   
  13.     }   
  14.     public MyClassLoader(ClassLoader parent,String name){   
  15.         super(parent);//设置该加载器的父加载器   
  16.         this.name = name;   
  17.     }   
  18.     //将java文件中的数据存储到字节数组中   
  19.     private byte[] loadClassData(String name){   
  20.         byte[] data = null;//存储字节码   
  21.         InputStream ips = null;   
  22.         ByteArrayOutputStream baos = null;   
  23.         try{   
  24.             String cname = name.replace(".", "\\");//获取正确的路径格式  
  25.              ips = new FileInputStream(new File(path+cname+fileType));   
  26.             baos = new ByteArrayOutputStream();   
  27.             int ch = 0;   
  28.             while(-1 != (ch = ips.read()) ){   
  29.                 baos.write(ch);//从文件输入流中读取数据,将读到的数据写到字节数组输出流中   
  30.             }   
  31.             data = baos.toByteArray();  //将输出流中的中的数据存入到字节数组data中。
  32.              ips.close();   
  33.             baos.close();//关闭输入输出流   
  34.         }catch(Exception ep){   
  35.             ep.printStackTrace();   
  36.         }   
  37.         return data;   
  38.     }
  39.    
  40.    
  41.     //获取Class对象 ,在通过父类加载器检查所请求的类后,此方法将 loadClass 方法调用。
  42.      public Class<?> findClass(String name) throws ClassNotFoundException
  43.     //自己定义的加载器覆盖父类的findClass方法。是为了将.class 文件的数据转换成字节码。
  44.      {   
  45.      byte[] data = this.loadClassData(name); // 获得2进制数据。
  46.          return this.defineClass(name, data, 0, data.length);   //将上述的2进制数据变成class 字节码。
  47.      }   
  48.     public String getPath() {   
  49.         return path;   
  50.     }   
  51.     public void setPath(String path) {   
  52.         this.path = path;   
  53.     }   
  54.     public String toString(){   
  55.         return this.name;   
  56.     }   
  57.     //测试方法   
  58.     public static void test(ClassLoader loader) throws Exception{   
  59.         Class<?> c = loader.loadClass("First");   
  60.         c.newInstance();   
  61.     }   
  62.     public static void main(String[] args) throws Exception {   
  63.         MyClassLoader loader1 = new MyClassLoader("loader1");   //创建自己的类加载器名叫loader1
  64.          loader1.setPath("F:\\myapp\\loader1\\");   
  65.         MyClassLoader loader2 = new MyClassLoader(loader1,"loader2");   
  66.         loader2.setPath("F:\\myapp\\loader2\\");   
  67.         test(loader1);  //  通过test方法测试 First 类的加载。
  68.          test(loader2);   
  69.     }   
  70. }  
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马