1.动态编译
- Java 6.0 引入了编译机制
-
动态编译的应用场景:
- 可以做一个浏览器端编写java代码,上传服务器编译和运行的在线评测系统
- 服务器动态加载某些类文件进行编译
-
动态编译的两种做法:
- 通过Runtime调用javac,启动新的进程去操作(6.0之前,不是真正的动态编译)
Runtime run = Runtime.getRuntime();
Process process = run.exec("javac -cp d:/myjava/Helloworld.java")
- 通过JavaCompiler动态编译
- 通过Runtime调用javac,启动新的进程去操作(6.0之前,不是真正的动态编译)
- 通过JavaCompiler动态编译
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "f:/HelloWorld.java");
Parameters:in "standard" input; use System.in if nullout "standard" output; use System.out if nullerr "standard" error; use System.err if nullarguments arguments to pass to the tool
栗子:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();int result = compiler.run(null, null, null, "f:/HelloWorld.java");System.out.println(result==0?"编译成功":"编译失败");
2.动态运行编译好的类
- 通过Runtime.getRuntime()运行启动新的进程运行
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();int result = compiler.run(null, null, null, "f:/HelloWorld.java");System.out.println(result==0?"编译成功":"编译失败");Runtime run = Runtime.getRuntime();Process process = run.exec("java -cp f: HelloWorld"); BufferedReader w = new BufferedReader(new InputStreamReader(process.getInputStream()));System.out.println(w.readLine());
- 通过反射运行编译好的类
import java.io.IOException;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import javax.tools.JavaCompiler;import javax.tools.ToolProvider;public class DynamicCompile { public static void main(String[] args) throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int result = compiler.run(null, null, null, "f:/HelloWorld.java"); System.out.println(result==0?"编译成功":"编译失败"); try { URL[] urls = new URL[]{new URL("file:/"+"f:/")}; URLClassLoader loader = new URLClassLoader(urls); Class c = loader.loadClass("HelloWorld"); Method m = c.getMethod("main", String[].class); m.invoke(null, (Object)new String[]{});//静态方法不用谢调用的对象 //加Object强制转换的原因 //由于可变参数是JDK5.0之后才有 m.invoke(null, new String[]{"23","34"}); //编译器会把它编译成m.invoke(null,"23","34");的格式,会发生参数不匹配的问题 //带数组的参数都这样做 } catch (Exception e) { e.printStackTrace(); } }}