自定义类加载器

自定义类加载器

自定义类加载器的流程

1.首先检查请求的类型是否已经被这个类装载器装载到命名空间中了,如果已经装载,直接返回;否则转入步骤2

2.委派类加载请求给父类加载器(更准确的说应该是双亲类加载器,真个虚拟机中各种类加载器最终会呈现树状结构),如果父类加载器能够完成,则返回父类加载器加载的Class实例;否则转入步骤3

3.调用本类加载器的findClass(…)方法,试图获取对应的字节码,如果获取的到,则调用defineClass(…)导入类型到方法区;如果获取不到对应的字节码或者其他原因失败,返回异常给loadClass(…), loadClass(…)转抛异常,终止加载过程(注意:这里的
异常种类不止一种)。
注意:被两个类加载器加载的同一个类,JVM不认为是相同的类。


自定义"文件系统类加载器"代码实现如下:

package 测试类加载全过程;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * 自定义文件系统类加载器
 */
public class FileSystemClassLoader extends ClassLoader{
   
	
	private String rootDir;
	
	public FileSystemClassLoader(String rootDir) {
   
		this.rootDir=rootDir;
	}
	
	//com.xyj.test.User  --> f:/MyJava/com/xyj/test/User.class
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
   
		//先查找已加载的类,看有没有已经被加载过
		Class<?> c = findLoadedClass(name);
		//如果已经加载过 就return回去
		if(c!=null) {
   
			return c;
		}else {
   
			//如果没有被加载过 委派父类去加载
			ClassLoader parent = this.getParent();
			
			try {
   //此try-catch的作用是出了异常继续往下走
				c=parent.loadClass(name);//委派父类去加载
			} catch (Exception e) {
   
				//e.printStackTrace();
			}
			
			if(c!=null) {
   
				return c;
			}else {
   
				//如果还是没找到 则读取路径下的class文件转换为字节数组
				byte [] classData=getClassData(name);
				if(classData==null) {
   
					throw new ClassNotFoundException();
				}else {
   
					c=defineClass(name,classData,0,classData.length);//将字节数组转换为类别 Class的实例
				}
			}
		}
		return c;
	}

	private byte[] getClassData(String className) {
   //com.xyj.test.User  --> f:/MyJava/com/xyj/test/User.class
		String path=rootDir+"/"+className.replace('.','/')+".class";
		InputStream is=null;
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		try {
   
			is=new FileInputStream(path);
			
			byte [] buffer=new byte[1024];
			int len=-1;
			while((len=is.read(buffer))!=-1) {
   
				baos.write(buffer, 0, len);
			}
			baos.flush();
			
			return baos.toByteArray();
		
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值