黑马程序员技术交流社区

标题: 如何直接让我自定义的类加载器加载类,而不委托给..... [打印本页]

作者: 知行    时间: 2013-6-11 11:44
标题: 如何直接让我自定义的类加载器加载类,而不委托给.....
本帖最后由 知行 于 2013-6-14 22:57 编辑

如何直接让我自定义的类加载器加载指定类,而不委托给它的父类。

作者: 燃灯街    时间: 2013-6-11 16:51
要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用。具体的实现你可以参看下面的这个例子:

public class MyClassLoader extends ClassLoader {

    //类加载器名称
    private String name;
    //加载类的路径
    private String path = "D:/";
    private final String fileType = ".class";
    public MyClassLoader(String name){
        //让系统类加载器成为该 类加载器的父加载器
        super();
        this.name = name;
    }

    public MyClassLoader(ClassLoader parent, String name){
        //显示指定该类加载器的父加载器
        super(parent);
        this.name = name;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public String toString() {
        return this.name;
    }

    /**
     * 获取.class文件的字节数组
     * @param name
     * @return
     */
    private byte[] loaderClassData(String name){
        InputStream is = null;
        byte[] data = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        this.name = this.name.replace(".", "/");
        try {
            is = new FileInputStream(new File(path + name + fileType));
            int c = 0;
            while(-1 != (c = is.read())){
                baos.write(c);
            }
            data = baos.toByteArray();

        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            try {
                is.close();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

    /**
     * 获取Class对象
     */
    @Override
    public Class<?> findClass(String name){
        byte[] data = loaderClassData(name);
        return this.defineClass(name, data, 0, data.length);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //loader1的父加载器为系统类加载器
        MyClassLoader loader1 = new MyClassLoader("loader1");
        loader1.setPath("D:/lib1/");
        //loader2的父加载器为loader1
        MyClassLoader loader2 = new MyClassLoader(loader1, "loader2");
        loader2.setPath("D:/lib2/");
        //loader3的父加载器为根类加载器
        MyClassLoader loader3 = new MyClassLoader(null, "loader3");
        loader3.setPath("D:/lib3/");

        Class clazz = loader2.loadClass("Sample");
        Object object = clazz.newInstance();
    }
}
作者: 袁梦希    时间: 2013-6-12 19:19
燃灯街 发表于 2013-6-11 16:51
要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法 ...

尽量把代码编辑到代码块里  这样看着方便  加油
作者: 袁梦希    时间: 2013-6-12 19:20
楼主尽量提问题时  尽量详细  这样方便大家回答
作者: 袁梦希    时间: 2013-6-12 19:20
楼主你好  如果问题已经解决  请把帖子的类型改为已解决  然后会给你发几个粽子吃
作者: 知行    时间: 2013-6-12 22:36
燃灯街 发表于 2013-6-11 16:51
要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法 ...

调用的时候,不是先调用类加载器的loadClass 方法,然后委托给自己的父类,直接覆盖findClass(String name)的话,在加载的时候还是会先用父类加载的,是吗?
作者: 知行    时间: 2013-6-12 22:36
袁梦希 发表于 2013-6-12 19:20
楼主尽量提问题时  尽量详细  这样方便大家回答

好的:lol




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