java自定义类加载器

package test97;

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[] getBytes(String filename) throws IOException {
        File file = new File(filename);
        long len = file.length();
        byte[] raw = new byte[(int)len];
        FileInputStream fis = new FileInputStream(file);
        int r = fis.read(raw);
        if (r != len) {
            throw new IOException("无法加载全部文件");
        }
        fis.close();
        return raw;
    }
    //定义编译指定java文件的方法
    private boolean compile(String javaFile) throws IOException {
        System.out.println("CompileClassLoader正在编译:" + javaFile + ".....");
        //调用系统的javac命令
        Process p = Runtime.getRuntime().exec("javac " + javaFile);
        try {
            //其他线程都等待这个线程完成
            p.waitFor();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        //获取javac线程退出值
        int ret = p.exitValue();
        //返回编译是否成功
        return ret == 0;
    }
    //重写ClassLoader的findClass方法
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> clazz = null;
        //将包路径中的"."替换为"/"
        String fileStub = name.replace(".", "/");
        String javaFilename = fileStub + ".java";
        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()) {
            try {
                //如果编译失败或者class文件不存在
                if (!compile(javaFilename) || !classFile.exists()) {
                    throw new ClassNotFoundException("class not found exception" + javaFilename);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (classFile.exists()) {
            try {
                //将class文件的二进制数据读入数组中
                byte[] raw = getBytes(classFilename);
                //调用ClassLoader的defineClass方法将二进制数据转换成Class对象
                clazz = defineClass(name,raw,0,raw.length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (clazz == null) {
            throw new ClassNotFoundException(name);
        }
        return clazz;
    }
    public static void main(String[] args) throws Exception {
        //如果运行该程序时没有参数,即没有目标类
        if (args.length < 1) {
            System.out.println("缺少运行的目标类,请按如下格式运行java源文件");
            System.out.println("java CompileClassLoader ClassName");
        }
        //第一个参数是要运行的类
        String progClass = args[0];
        System.out.println(progClass);
        //剩下的参数将作为运行目标时的参数,所以将这些参数复制到一个新的数组中
        String progArray[] = new String[args.length-1];
        System.arraycopy(args, 1, progArray, 0, progArray.length);
        CompileClassLoader ccl = new CompileClassLoader();
        //加载需要运行的类
        Class<?> clazz = ccl.loadClass(progClass);
        //获取运行类的主方法
        Method main = clazz.getMethod("show", new Class[]{});
        System.out.println((new String[0]).getClass());
        Object argsArray[] = {progArray};
        //main.invoke(null, argsArray);
        ccl.invokeMethod(main, argsArray);
    }
    public void invokeMethod(Method main, Object argsArray[]) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        main.invoke(new StaticTest(), null);
    }
}


参考书籍:疯狂java讲义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值