动态编译

有时候我们有这样一个需求:将动态生成的内容进行编译

比如说用户在客户端浏览器输入一段代码传到服务器,服务器拿到这段代码进行编译。

动态编译的两种做法:

(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,第二个参数一定要强转。

 

posted on 2016-09-20 14:23  loveLiv  阅读(469)  评论(0)    收藏  举报

导航