java import自定义类_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);Java多线程Queue总结

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);

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值