动态编译
有时候我们有这样一个需求:将动态生成的内容进行编译
比如说用户在客户端浏览器输入一段代码传到服务器,服务器拿到这段代码进行编译。
动态编译的两种做法:
(1)通过Runtime调用javac,启动新的进程去操作它。
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("javac -cp c:/myjava/ HelloWorld.java");
(2)通过JavaCompiler动态编译
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null,null,null,sourceFile);
参数介绍:
第一个参数:为Java编译器提供参数
第二个参数:得到Java编译器的输出信息
第三个参数:接收Java编译器的错误信息
第四个参数:是一个可变数组String[],能传入一个或多个Java文件
返回值:0表示编译成功,非0表示编译失败
下面写一个demo供参考
首先我们在d盘根目录下建立一个myjava文件夹,在myjava文件夹中新建一个java类,名字叫HelloWorld.java
1 package com.coscon.compiler; 2 3 import javax.tools.JavaCompiler; 4 import javax.tools.ToolProvider; 5 6 public class JavaCompilerTest { 7 public static void main(String[] args) { 8 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 9 int result = compiler.run(null, null, null, "d:/myjava/HelloWorld.java"); 10 System.out.println(result==0?"编译成功":"编译失败"); 11 } 12 }
控制台打印编译成功,同时在myjava文件夹中出现.class文件。
如果我们需要动态编译一个字符串,比如说在上面这个Java类中有一个String str = "public class Demo2{public static void main(String[] args){System.out.print(\"编译字符串\")}}";
我们可以通过io流将上述字符串存入到一个临时文件中,后缀名为.java,在调用JavaCompiler的run方法进行动态编译。
动态编译好类之后,有时候我们需要动态地去运行这些编译好的类。
这边也对应两种方法:
(1)通过Runtime调用java,启动新的进程去操作它。
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("java -cp c:/myjava/ HelloWorld");
直接运行的话控制台无法获取打印信息。
InputStream in = process.getInputStream();
BufferedReader reader = new BufferedReader(new inputStreamReader(in));
string info = "";
while((info=reader.readLine())!=null){
System.out.println(info);
}
这样就实现了两个进程间的交互。
(2)通过反射运行编译好的类
URL[] urls = new URL[]{new URL("file:/"+"d:/myjava/")};
URLClassLoader loader = new URLClassLoader(urls);
Class c = loader.loaderClass("HelloWorld");
//调用加载类的mian方法
Method m = c.getMethod("main",String[].class);
m.invoke(null,(Object)new String[]{});//调用静态方法,可以传null,第二个参数一定要强转。
浙公网安备 33010602011771号