(JavaSE 学习记录) 自定义类加载器

自定义类加载器

1、继承 java.lang.ClassLoader
2、检查加载的类是否已经被装载,若已经装载,直接返回
3、委派类加载请求给父类加载器,若父类能完成,返回父类加载器加载的Class实例
4、调用本类加载器findClass方法,试图获取对应字节码,若成功则调用defineClass导入类型到方法区,失败则返回异常。

import java.io.*;

//继承 java.lang.ClassLoader
public class FileSystemClassLoader extends ClassLoader {

    private String rootDir;

    public FileSystemClassLoader(String rootDir){
        this.rootDir = rootDir;
    }
    //findClass方法
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> c = findLoadedClass(name);

        //是否已被加载
        if (c!=null){
            return c;
        }else {
            //双亲委托
            ClassLoader parent = this.getParent();

            //避免在此停止
            try {
                c = parent.loadClass(name);
            }catch (Exception e){

            }

            if (c!=null){
                return c;
            }else {
                //获取对应字节数组
                byte[] classData = getClassData(name);
                if (classData == null){
                    throw new ClassNotFoundException();
                }else{
                    //利用defineClass导入类型到方法区
                    c=defineClass(name,classData,0,classData.length);
                }
            }
        }
        return c;
    }
    
    //获取字节数组对应方法
    private byte[] getClassData(String name){
        String path = rootDir+"/"+name.replace('.','/')+".class";
        InputStream is = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            is = new FileInputStream(path);
            byte[] flush = new byte[1024];
            int len ;
            while((len = is.read(flush))!=-1){
                baos.write(flush,0,len);
            }
            return baos.toByteArray();
        }  catch (IOException e) {
            e.printStackTrace();
            return null;
        }finally {
            try {
                if (is!=null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

测试:同一个类被不同加载器加载,jvm认为是不同的

    public static void main(String[] args) throws ClassNotFoundException {
        FileSystemClassLoader loader = new FileSystemClassLoader("D:/JavaNote");
        FileSystemClassLoader loader02 = new FileSystemClassLoader("D:/JavaNote");
        Class<?> c = loader.loadClass("Test");
        Class<?> c2 = loader.loadClass("Test");
        Class<?> c3 = loader02.loadClass("Test");

        Class<?> c4 = loader.loadClass("java.lang.String");
        Class<?> c5 = loader.loadClass("Re.Test");

        System.out.println(c.hashCode());
        System.out.println(c2.hashCode());  //与c相同
        System.out.println(c3.hashCode());  //与c、c2相同,同一个类被不同加载器加载,jvm认为是不同的
        System.out.println(c4.hashCode());

        System.out.println(c5.getClassLoader()); //系统默认加载器
        System.out.println(c3.getClassLoader()); //自定义加载器
        System.out.println(c4.getClassLoader()); //null 引导类加载器
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值