服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

扩展classloader定制类装载器

    java的classloader与package机制介绍了classloader的委派机制,它是把装载的任务传递给上级的装载器的,依次类推,直到启动类装载器(没有上级类装载器)。如果启动类装载器能够装载这个类,那么它会首先装载。如果不能,则往下传递。其实这引出一个运行时包的概念。不同装载器装载的类,即使包名相同也不能互相访问。这样保证了核心类库不被破坏。

    本文将讲述如何扩展classloader类实现一个自己的类装载器,每个class对象都有一个引用指向装载他的classloader,你可以通过public classloader getclassloader()方法得到它。为了创建自己的类装载器我们应该扩展classloader类,这是一个抽象类。我们目的是从本地文件系统使用我们实现的类装载器装载一个类。我们创建一个fileclassloader extends classloader。我们需要覆盖classloader中的
findclass(string name)方法,这个方法通过类的名字而得到一个class对象。
    public class findclass(string name)
    {
        byte[] data = loadclassdata(name);
        return defineclass(name, data, 0, data.length);
    }
我们还应该提供一个方法loadclassdata(string name),通过类的名称返回class文件的字节数组。然后使用classloader提供的defineclass()方法我们就可以返回class对象了。
    public byte[] loadclassdata(string name)
    {
        fileinputstream fis = null;
        byte[] data = null;
        try
        {
            fis = new fileinputstream(new file(drive + name + filetype));
            bytearrayoutputstream baos = new bytearrayoutputstream();
            int ch = 0;
            while ((ch = fis.read()) != -1)
            {
                baos.write(ch);
              
            }
            data = baos.tobytearray();
        } catch (ioexception e)
        {
            e.printstacktrace();
        }
       
        return data;
    }
这里我们是从d盘装载一个类。

     下面我们提供一个类public class myapp{},类中没有定义任何方法和变量,下面我们编译myapp.java得到myapp.class,然后把文件放在d盘的根目录。为了证明myapp.class是被我们定义的classloader装载的,我们在fileclassloader的main()方法中打印出装载myapp.class的类装载器的名称。
    public static void main(string[] args) throws exception
    {
        fileclassloader loader = new fileclassloader();
        class objclass = loader.loadclass("myapp", true);

        object obj = objclass.newinstance();
        system.out.println(objclass.getname());
        system.out.println(objclass.getclassloader());
     
            
     }
编译fileclassloader
javac fileclassloader.java  然后运行java fileclassloader 可以看到输出结果为
myapp
fileclassloader@1a5ab41
如果你把myapp.class放入到你程序的所在目录会出现什么情况呢?读者自己实践一下吧!下面给出fileclassloader的源代码。
import java.io.bytearrayoutputstream;
import java.io.file;
import java.io.fileinputstream;
import java.io.ioexception;

public class fileclassloader extends classloader
{
    public static final string drive = "d:/";
    public static final string filetype = ".class";
 
    public fileclassloader() {
        super();
 
    }
 
    public fileclassloader(classloader arg0) {
        super(arg0);
    }
 
    public class findclass(string name)
    {
        byte[] data = loadclassdata(name);
        return defineclass(name, data, 0, data.length);
    }
 
    public byte[] loadclassdata(string name)
    {
        fileinputstream fis = null;
        byte[] data = null;
        try
        {
            fis = new fileinputstream(new file(drive + name + filetype));
            bytearrayoutputstream baos = new bytearrayoutputstream();
            int ch = 0;
            while ((ch = fis.read()) != -1)
            {
                baos.write(ch);
              
            }
            data = baos.tobytearray();
        } catch (ioexception e)
        {
            e.printstacktrace();
        }
       
        return data;
    }
   
 
    public static void main(string[] args) throws exception
    {
        fileclassloader loader = new fileclassloader();
        class objclass = loader.loadclass("myapp", true);

        object obj = objclass.newinstance();
        system.out.println(objclass.getname());
        system.out.println(objclass.getclassloader());
     
            
     }
}

扫描关注微信公众号