Java虚拟机(八):自定义类加载器

 

Java虚拟机(八):自定义类加载器

本文包括:

一.为什么需要自定义类加载器

二.如何自定义类加载器

三.自定义类加载器例子


一.为什么需要自定义类加载器

默认的类加载器只知道如何从本地系统加载类。如果我们的程序只是在本机跑的话,一般来说默认加载器可以应付。但是如果我们需要加载远程服务器的类,或者说加载网络上的,不是本机上的类的时候,就需要到自定义类加载器。

二.如何自定义类加载器

自定义类加载器可以选择继承ClassLoader类,重写里面的方法来实现。里面有三个重要的方法,一个是loadClass()方法,一个是findClass()方法,一个是defineClass()方法。

对于loadClass(String name,Boolean resolve)方法:不推荐重写,因为loadClass()方法做的工作主要为实现双亲委托模型,我们重写的话可能会破坏该模型,并且也增加自己的开发难度。

对于defineClass(String name,byte[] b,int off,int len)方法,主要用于将原始字节转换为Class对象,也不需要我们重写。

对于findClass(String name)方法,根据名称来查找类。把.class文件的内容放入一个byte[]数组中,供defineClass()方法使用。一般我们就重写这个方法。在这个方法中,我们重新定义从哪里,怎么样读取文件内容。这样我们就可以把从本机上改为从网络上得到类,从而实现自定义类加载器。

总而言之:1.继承ClassLoader类。2.重写findClass(String name)方法。 3.在这个方法里面我们重新定义从哪里,怎么读取文件内容到byte[]数组中,供defineClass()使用。

三.自定义类加载器例子

[java]  view plain copy
  1. public class Sample{  
  2.     public int v1 = 1;  
  3.     public Sample(){  
  4.         System.out.println(“Sample is load by :” + this.getClass().getClassLoader());  
  5.     }  
  6. }  
  7. import java.io.ByteArrayOutputStream;  
  8. import java.io.File;  
  9. import java.io.FileInputStream;  
  10. import java.io.InputStream;  
  11.   
  12. public class MyClassLoader extends ClassLoader{  
  13.     private String name;  
  14.     private String path = ”d:\\”;  
  15.     private final String fileType = ”.class”;  
  16.       
  17.     public MyClassLoader(String name){  
  18.         super();  
  19.         this.name = name;  
  20.     }  
  21.     public MyClassLoader(ClassLoader parent, String name){  
  22.         super(parent);  
  23.         this.name = name;  
  24.     }  
  25.     @Override  
  26.     public String toString(){return this.name;}    
  27.     public String getName(){return name;}  
  28.     public void setName(String name){this.name = name;}    
  29.     public String getPath(){return path;}      
  30.     public void setPath(String path){this.path = path;}   
  31.     public String getFileType(){return fileType;}      
  32.       
  33.     protected Class<?> findClass(String name) throws ClassNotFoundException{  
  34.         byte[] data = this.loadClassData(name);   
  35.         return this.defineClass(name, data, 0, data.length);  
  36.     }  
  37.     private byte[] loadClassData(String name){  
  38.         InputStream is = null;  
  39.         byte[] data = null;  
  40.         ByteArrayOutputStream baos = null;  
  41.         try{  
  42.             this.name = this.name.replace(“.”, ”\\”);  
  43.             is = new FileInputStream(new File(path + name + fileType));  
  44.             baos = new ByteArrayOutputStream();  
  45.             int ch = 0;  
  46.             while (-1 != (ch = is.read())){  
  47.                 baos.write(ch);  
  48.             }  
  49.             data = baos.toByteArray();  
  50.         }catch (Exception e){  
  51.             e.printStackTrace();  
  52.         }finally{  
  53.             try{  
  54.                 is.close();  
  55.                 baos.close();  
  56.             }catch (Exception e){  
  57.                 e.printStackTrace();  
  58.             }  
  59.         }  
  60.         return data;  
  61.     }  
  62.     public static void showClassLoader(ClassLoader loader) throws Exception{  
  63.         Class clazz = loader.loadClass(“Sample”);  
  64.         Object object = clazz.newInstance();  
  65.     }  
  66.     public static void main(String[] args) throws Exception{  
  67.         MyClassLoader loader1 = new MyClassLoader(“loader1″);  
  68.         loader1.setPath(“d:\\loader1\\”);  
  69.         MyClassLoader loader2 = new MyClassLoader(loader1, ”loader2″);  
  70.         loader2.setPath(“d:\\loader2\\”);  
  71.         MyClassLoader loader3 = new MyClassLoader(null, ”loader3″);  
  72.         loader3.setPath(“d:\\loader3\\”);  
  73.         showClassLoader(loader2);  
  74.         showClassLoader(loader3);  
  75.     }  
  76. }  
这段代码主要为大家展示了怎么自定义一个类加载器。

1.继承ClassLoader。

2.重写findClass()。

3.在findClass()方法里面我们重新定义从哪里,怎么读取文件内容到byte[]数组中,供defineClass()使用。


四.参考

http://www.strutshome.com/index.php/archives/525

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值