JavaCompiler实战:将Java源代码字符串动态编译成java类
.首先我们来认识一下 java中的一个对象 JavaCompiler
JavaCompiler : 不知道肯定很陌生,其实这个api出来很久了,他是jdk6的特性,用来编译java的源程式的,详细介绍可以参考百度或google一下,介绍都很详细
Java的反射 : 这个我不多做介绍了,程序中很常见,基本上java程序员都会接触到,列入金典的框架 spring 等等
/** * 装载字符串成为java可执行文件 * @param className className * @param javaCodes javaCodes * @return Class */ private Class<?> compile(String className, String javaCodes) { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); StrSrcJavaObject srcObject = new StrSrcJavaObject(className, javaCodes); Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(srcObject); String flag = "-d"; String outDir = ""; try { File classPath = new File(Thread.currentThread().getContextClassLoader().getResource("").toURI()); outDir = classPath.getAbsolutePath() + File.separator; } catch (URISyntaxException e1) { e1.printStackTrace(); } Iterable<String> options = Arrays.asList(flag, outDir); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, fileObjects); boolean result = task.call(); if (result == true) { try { return Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return null; }
上面的代码也是较为核心的部分 ,就是将我们的字符串转换成一个java类,然后编译成class 重点看call(),
call(): 此方法就是进行动态编译可执行的代码
接下来我们得到编译完成的class , 成功后class已经加载到内存中了,我们这是只需要通过java的反射去找到该类文件并执行它就好了
private Object run(String method,String codes){ String className = "com.test.Eval"; StringBuilder sb = new StringBuilder(); sb.append("package com.test;"); sb.append(" public class Eval{ "); sb.append(codes); sb.append(" }"); Class<?> clazz = compile(className, sb.toString()); try { // 生成对象 Object obj = clazz.newInstance(); Class<? extends Object> cls = obj.getClass(); // 调用main方法 Method m = clazz.getMethod(method,String[].class); Object invoke = m.invoke(obj, new Object[] { new String[] {} }); return invoke; } catch (Exception e) { e.printStackTrace(); return null; } }
好了,代码完成,我们看一下执行结果
public static Object eval() { Eval eval = mWeakReference.get(); String method = "main"; String codes = "public static void main(String[]args){" + "System.out.print("hello world"); }"; eval.run(method,codes); return null; } public static void main(String[] args) { eval(); }
Java eval demo 地址 :
上一篇:
IDEA上Java项目控制台中文乱码