java自定义类加载器

java的加载器分为三类

引导加载器 C编写

扩展加载器

应用程序加载器

加载的过程 是从上到下的顺序。跟windows的消息钩子的执行方向相反。
之前CC++写过pe文件加载 非常麻烦,按照pe格式分配内存加载到程序空间

java提供了自定义加载器的机制 还是比较方便的,
总体流程:继承ClassLoader—-看看有没有加载过该类—-没有加载过看看父类能不能加载—-父类不能加载,自己去加载—-自己加载的流程—-获得类文件的byte[]—-调用父类接口defineClass得到Class对象

贴代码

自定义从文件加载类

package top.demo.load;

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

public class FileLoad extends ClassLoader{

    public String rootPath;
    //F:

    public FileLoad(String rootPath) {
        super();
        this.rootPath=rootPath;

    }


    //className top.demo.load.Test
    public Class<?> loadFileClass(String className) throws Exception {
        Class<?>cl=null;
        try {
            cl=findClass(className);
        } catch (ClassNotFoundException e) {
            //e.printStackTrace();
            System.out.println("没有加载过该类");
        }

        if(cl!=null)            
            return cl;

        //如果该类没有被加载 交由父类加载
        try {
            cl=super.loadClass(className);
        } catch (ClassNotFoundException e) {
            //e.printStackTrace();
            System.out.println("父类不能加载该类");
        }

        if(cl!=null)
            return cl;

        //如果父类不能加载,那么我们自己加载
        StringBuilder realPath=new StringBuilder();
        realPath.append(rootPath);
        realPath.append("/");
        realPath.append(className.replace(".", "/"));
        realPath.append(".class");

        File file=new File(realPath.toString());
        if(!file.exists()) {
            throw new Exception("没有这个类文件存在");
        }

        byte[] classInfo=null;

        classInfo=getClassFileInfo(file);
        if(classInfo==null) {
            throw new Exception("读取类文件可能出错");
        }

        cl=defineClass(className,classInfo, 0, classInfo.length);

        if(cl==null)
            throw new Exception("自定义加载器出错");


        return cl;
    }

    private byte[] getClassFileInfo(File file) {

        byte[] classInfo=new byte[(int) file.length()];
        FileInputStream fileIn=null;

        try {
            int len=0;
            fileIn=new FileInputStream(file);

            try {
                while(-1!=(len=fileIn.read(classInfo))) {

                }
            } catch (IOException e) {
                e.printStackTrace();
                classInfo=null;
                try {
                    fileIn.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            classInfo=null;
        }finally {
            try {
                fileIn.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }



        return classInfo;
    }


}

定义需要加载的类 并且编译成class文件放在 F:\top\demo\load下类名为Test

定义测试加载类

package top.demo.load;

public class TestLoad {

    public static void main(String argv[])
    {

        FileLoad load=new FileLoad("F:");
        Class<?> cl=null;
        try {
            cl=load.loadFileClass("top.demo.load.Test");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(cl!=null ? "成功加载":"加载失败");



    }


}

输出结果

没有加载过该类
父类不能加载该类
成功加载

猜你喜欢

转载自blog.csdn.net/qq_27617675/article/details/82558551