Java 动态编译源码,并通过反射执行编译后的代码的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 import java.io.File;import java.lang.reflect.Method;import java.net.URI;import java.net.URL;import java.net.URLClassLoader;import java.util.Arrays;import javax.tools.JavaCompiler;import javax.tools.JavaFileObject;import javax.tools.SimpleJavaFileObject;import javax.tools.ToolProvider;public class DynamicCompiler { public Class compile (String sourceCode) throws Exception { File distDir = new File("target" ); if (!distDir.exists()) { distDir.mkdirs(); } JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); String className = getFullClassNameFromCode(sourceCode); JavaFileObject javaFileObject = new CodeJavaFileObject(className, sourceCode); JavaCompiler.CompilationTask task = compiler.getTask(null , null , null , Arrays.asList("-d" , distDir.getAbsolutePath()), null , Arrays.asList(javaFileObject)); boolean compileSuccess = task.call(); if (!compileSuccess) { System.out.println("compile failed" ); return null ; } else { System.out.println("compile successed " + distDir.getAbsolutePath()); URL[] urls = new URL[] {new URL("file://" + distDir.getAbsolutePath() + "/" )}; URLClassLoader classLoader = new URLClassLoader(urls); Class dynamicClass = classLoader.loadClass(className); return dynamicClass; } } class CodeJavaFileObject extends SimpleJavaFileObject { private String code; public CodeJavaFileObject (String className, String code) { super (URI.create(className.replaceAll("\\." , "/" ) + Kind.SOURCE.extension), Kind.SOURCE); this .code = code; } @Override public CharSequence getCharContent (boolean ignoreEncodingErrors) { return code; } } private String getFullClassNameFromCode (String code) { String t = code.substring(0 , code.indexOf('{' )); String s = t.replaceAll("[\r\n\t]" , " " ).trim(); String[] ary = s.split("[;]" ); String packageName = null ; String className = getLastPart((ary[ary.length - 1 ])); if (ary[0 ].startsWith("package " )){ packageName = getLastPart(ary[0 ]); return packageName + "." + className; }else { return className; } } private String getLastPart (String s) { String[] ary = s.trim().split(" " ); return ary[ary.length - 1 ]; } public static void main (String[] argvs) throws Exception { StringBuffer buf = new StringBuffer(); buf.append("package a.b.c;\r\npublic class ANumber{" ) .append("public int getNumber() {" ) .append("System.out.println(\"Hello World in getNumber()!\"); return 999;" ) .append("}" ) .append("}" ); DynamicCompiler dc = new DynamicCompiler(); Class cls = dc.compile(buf.toString()); System.out.println(cls.getName()); Object obj = cls.getDeclaredConstructor().newInstance(); Method method = cls.getDeclaredMethod("getNumber" ); Object r = method.invoke(obj); System.out.println("result is " + r); } }