自定义类加载器源码实现

1.自定义类加载器

继承ClassLoader,重写findClass()方法

package com.wpao.classloader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

//自定义类加载器,用于加载特定路径下的class文件
public class MyClassLoader extends ClassLoader{
    
    private String url;//class文件的路径,类加载器用于加载特定路径下的class文件
    private String name;//类加载器的名字
    
    public MyClassLoader(ClassLoader parent,String url, String name) {
        super(parent);//使用指定的 父类加载器
        this.url = url;
        this.name = name;
    }

    public MyClassLoader(String url,String name) {
        super();//使用系统默认的加载器作为该加载器的父类
        this.url = url;
        this.name = name;
    }


    //读取class文件为二进制的字节输入流,并转化为Class对象
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] date = readClassToBytes(name);//将文件通过输入流转化为字符数组
        Class<?> c = defineClass(name, date, 0, date.length);//调用ClassLoader的defindClass方法,转化字符数组为对应的Class实例
        return c;
    }
    
    //读取Class文件生成字节数组
    private byte[] readClassToBytes(String name){
        name = name.replaceAll("\\.", "/");
        String fileName = url + name + ".class";
        FileInputStream is = null;
        byte[] date = null;
        try {
            File file = new File(fileName);
            is = new FileInputStream(file);//输入流
            int length = is.available();
            date = new byte[length];
            is.read(date);//输入流读入字符数组中
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        return date;
    }
    
    @Override
    public String toString() {
        return name;//当前类加载器的名字
    }
}

 

2.测试类

package com.wpao.classloader;

public class Demo {
    private static String date = "Demo";
    public Demo() {
        System.out.println("构造方法:"+date+"  "+this.getClass().getClassLoader());
    }
}

3.main测试

通过调用loadClass()方法去加载类,而非使用findClass()方法

public class MyTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        
        //测试,非当前classpath下的Demo类的加载,该父类加载器为AppClassLoader
        MyClassLoader c1 = new MyClassLoader("D:/test/","父类加载器为AppClassLoader的类加载器");
        Class<?> cl1 = c1.loadClass("com.wpao.classloader.Demo");
        cl1.newInstance();//相当于调用其构造方法,开始进行加载
        
        //测试,非当前classpath下的Demo类的加载,该父类加载器为null即BootStrapClassLoader
        MyClassLoader c4 = new MyClassLoader(null,"D:/test/","父类加载器为null的类加载器");
        Class<?> cl4 = c4.loadClass("com.wpao.classloader.Demo");
        cl4.newInstance();
        
        MyClassLoader c3 = new MyClassLoader(c1,"D:/test/","父类加载器为自定义的类加载器");
        Class<?> cl3 = c3.loadClass("com.wpao.classloader.Demo");
        cl3.newInstance();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值