JAVA自定义类加载器

JAM中除了根加载器外,其他的加载器都是继承的ClassLoader。所以开发者可以定义自己的类加载器,然后重写ClassLoader的方法。通过查看API可以知道,ClassLoader有许多protected方法,这些都是可以用来重写的。

ClassLoader有几个重要方法:

findClass(String name);根据二进制类文件名来查找类

loadClass(String name,boolean resolve);该方法为ClassLoader的入口点,根据指定的二进制名称来加载类

但是一般推荐覆写第一个方法。

 

下面介绍自己写的ClassLoader

 

/**
 * @author:LYL
 * @date:2011-7-17,下午01:02:47
 * @description:自定义ClassLoader
 */
package com.lyl.reflect;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CompileClassLoader extends ClassLoader {
	// 读入源文件转换为字节数组
	private byte[] getSource(String filename) {
		File file = new File(filename);
		int length = (int) file.length();
		byte[] contents = new byte[length];
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			int r = fis.read(contents);
			if (r != length) {
				throw new IOException("IOException:无法读取" + filename);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return contents;
	}

	// 编译文件
	public boolean compile(String javaFile) {
		System.out.println("正在编译" + javaFile);
		int ret = 0;
		try {
			// 调用系统命令编译文件
			Process process = Runtime.getRuntime().exec("javac " + javaFile);
			process.waitFor();
			ret = process.exitValue();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return ret == 0;
	}

	// 重写findclass
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> clazz = null;
		// 将文件的.替换为/,例如com.lyl.reflect.Reflect被替换为com/lyl/reflect/Reflect
		String fileStub = name.replace(".", "/");
		// java源文件名
		String javaFileName = fileStub + ".java";
		// 编译后的class文件名
		String classFileName = fileStub + ".class";
		File javaFile = new File(javaFileName);
		File classFile = new File(classFileName);
		// 当指定JAVA源文件存在,且class文件不存在,
		// 或者java源文件的修改时间比class文件修改时间晚则重新编译
		if (javaFile.exists()
				&& (!classFile.exists() || javaFile.lastModified() > classFile
						.lastModified())) {
			// 如果编译失败,或者class文件不存在
			if (!compile(javaFileName) || !classFile.exists()) {
				throw new ClassNotFoundException("ClassNotFoundException:"
						+ javaFileName);
			}
		}
		// 如果CLASS文件按存在,系统负责将该文件转换成Class对象
		if (classFile.exists()) {
			byte[] raw = getSource(classFileName);
			// 将ClassLoader的defineClass方法将二进制数据转换成Class对象
			int divindex = name.indexOf("\\");
			String javafilename = null;
			// 如果是某个盘里面的文件,要去掉文件的盘符
			if (divindex != -1) {
				javafilename = name.substring(divindex + 1, name.length());
			}
			// 将字节数组转换为class实例
			clazz = defineClass(javafilename, raw, 0, raw.length);
		}
		// 如果clazz为null,表明加载失败,则抛出异常
		if (clazz == null) {
			throw new ClassNotFoundException(name);
		}
		return clazz;
	}

	// 定义主方法
	public static void main(String[] args) throws ClassNotFoundException,
			SecurityException, NoSuchMethodException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		// 如果运行该程序没有参数,则没有目标类
		if (args.length < 1) {
			System.out.println("缺少运行的目标类,请按如下格式运行源文件");
			System.out.println("java CompileClassLoader ClassName");
			System.exit(0);
		}
		// 第一个参数为需要运行的类
		String proClass = args[0];
		// 剩下的参数将作为目标类得参数
		String[] proArgs = new String[args.length - 1];
		System.arraycopy(args, 1, proArgs, 0, proArgs.length);
		CompileClassLoader ccl = new CompileClassLoader();
		// 加载需要运行的类
		Class<?> clazz = ccl.loadClass(proClass);
		Method main = clazz.getMethod("main", (new String[0]).getClass());
		Object[] argsArray = { proArgs };
		main.invoke(null, argsArray);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值