【java原生动态编程】字符串动态生成java文件并编译执行

一、常量

interface Constants {
    String BASEDIR = "D:\\";
    String SUFFIX = ".class";
}

二、重写类加载器到达加载指定目录的类

class MyClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) {
        String myPath = new File(Constants.BASEDIR + name + Constants.SUFFIX).toURI().toString();
        System.out.println(myPath);
        byte[] cLassBytes = null;
        Path path = null;
        try {
            path = Paths.get(new URI(myPath));
            cLassBytes = Files.readAllBytes(path);
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
        Class clazz = defineClass(name, cLassBytes, 0, cLassBytes.length);
        return clazz;
    }
}

三、Java动态编译

public class TrendsJava {

    public static void main(String[] args) {
        String code = "        System.out.println(\"Hello World!\"+(13+2*5/3));\n" +
                "        for (int i = 0; i <10; i++) {\n" +
                "            System.out.println(i);\n" +
                "        }";
        try {
            run(code);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private synchronized static File compile(String code) throws Exception {
        File file = File.createTempFile("JavaRuntime", ".java", new File(Constants.BASEDIR));
        file.deleteOnExit();
        // 获得类名
        String classname = getBaseFileName(file);
        // 将代码输出到文件
        PrintWriter out = new PrintWriter(new FileOutputStream(file));
        out.println(getClassCode(code, classname));
        out.close();


        // 编译生成的java文件
        String[] cpargs = new String[]{"-d", Constants.BASEDIR, file.getName()};

        System.out.println(System.getProperty("user.dir"));
        //动态编译
        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        int status = javac.run(null, null, null, "-d", Constants.BASEDIR, Constants.BASEDIR + file.getName());
        if (status != 0) {
            throw new Exception("语法错误!");
        }
        return file;
    }

    public static synchronized void run(String code) throws Exception {
        String classname = getBaseFileName(compile(code));
        new File(Constants.BASEDIR + classname + Constants.SUFFIX)
                .deleteOnExit();
        try {
            MyClassLoader loader = new MyClassLoader();

            Class cls = loader.findClass(classname);
            Method main = cls.getMethod("method", null);
            main.invoke(cls, null);
        } catch (Exception se) {
            se.printStackTrace();
        }
    }

    //将一块代码封装到 method函数中
    private static String getClassCode(String code, String className) {
        StringBuffer text = new StringBuffer();
        text.append("public class " + className + "{\n");
        text.append(" public static void method(){\n");
        text.append(" " + code + "\n");
        text.append(" }\n");
        text.append("}");
        return text.toString();
    }

    private static String getBaseFileName(File file) {
        String fileName = file.getName();
        if (fileName.contains(".")) {
            return fileName.split("\\.")[0];
        } else {
            return fileName;
        }

    }
}

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值