【Java动态编译】使用Java Compiler动态编译、使用示例代码
·
动态编译的应用场景
Java 6.0之后要引入了动态编译。
动态编译可以实现:让用户提交一段Java代码,上传到服务器,运行,实现在线评测系统。
Java 6.0之前,可以使用这种方式,达到动态编译的效果:
Java 6.0之后,使用如下方式,也就是本文要讲的:
- 使用
JavaCompiler动态编译

官方API
https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/tools/Tool.html#run(java.io.InputStream,java.io.OutputStream,java.io.OutputStream,java.lang.String...)

run
int run(InputStream in, OutputStream out, OutputStream err, String... arguments)
!!这里注意一下String... arguments,可以传进一个String数组,里面好像是所有需要编译的文件路径吧?
Run the tool with the given I/O channels and arguments. By convention a tool returns 0 for success and nonzero for errors. Any diagnostics generated will be written to either
out or err in some unspecified format.
-
Parameters:
-
in- "standard" input; use System.in if null -
out- "standard" output; use System.out if null -
err- "standard" error; use System.err if null -
arguments- arguments to pass to the tool Returns:
- 0 for success; nonzero otherwise Throws:
-
NullPointerException- if the array of arguments contains anynullelements.
动态编译
动态编译生成一个class文件
编译前:
编译后:
代码示例
下列代码返回值为0,表示编译成功
package cn.hanquan.dynamic;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class DynamicCompile {
public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "c:/picture/Hello.java");
System.out.println("result=" + result);
}
}
输出
result=0
提问:如果由于某种原因(如拼接…),需要编译的不是一个文件,而是一个字符串,那么应该如何编译呢?
- 可以通过IO流操作,将字符串存储成临时文件,然后调用动态编译方法
动态运行编译好的类

代码示例
(1)通过Runtime执行
package cn.hanquan.dynamic;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class DynamicCompile {
public static void main(String[] args) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "c:/picture/Hello.java");// 编译
if (result == 0) {
Runtime run = Runtime.getRuntime();// 运行
Process process = run.exec("java -cp c:/picture Hello");
InputStream is = process.getInputStream();// 获取运行后输出结果
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = "";
while ((info = br.readLine()) != null) {
System.out.println(info);
}
}
}
}
输出结果
Hello,World~~
(2)通过反射加载相关类,调用相关方法
注意42行,main方法没有参数,可以不写参数。传String数组的时候,一定要加Object进行转型。
更多推荐


所有评论(0)