• JAVA 6.0引入了动态编译机制。
• 动态编译的应用场景:
– 可以做一个浏览器端编写java代码,上传服务器编译和运行的在线评测 系统。
– 服务器动态加载某些类文件进行编译
• 动态编译的两种做法:
– 通过Runtime调用javac,启动新的进程去操作
Runtime run = Runtime.getRuntime();
Process process = run.exec("javac -cp d:/myjava/ HelloWorld.java");
– 通过JavaCompiler动态编译
public static int compileFile(String sourceFile){
//动态编译
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null,sourceFile);
System.out.println(result==0?"编译成功":"编译失败");
return result;
}
• 第一个参数:为java编译器提供参数
• 第二个参数:得到 Java 编译器的输出信息
• 第三个参数:接收编译器的 错误信息
• 第四个参数:可变参数(是一个String数组)能传入一个或多个 Java 源文件
• 返回值:0表示编译成功,非0表示编译失败
通过Runtime.getRuntime()运行启动新的进程运行
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class Demo01 {
public static void main(String[] args) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//获取编译器
//通过IO流把字符串保存为临时文件,然后用动态编译器方法
String str = "public class HelloWorld {public static void main(String[] args) {System.out.println(\"Hello World\");}}";
//通过文件路径编译java文件
int result = compiler.run(null, null, null, "D:/HelloWorld.java");
System.out.println(result==0?"编译成功":"编译失败");
//运行以上代码会出现空指针错误
//解决办法
//先进入jdk目录,进入lib目录,找到tools.jar包,点击复制到jre的lib目录下
//运行编译好的程序
Runtime run = Runtime.getRuntime();//
Process process = run.exec("java -cp d:/ HelloWorld");//编译文件名前要加空格
//获得打印的内容,读取内容
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String info = "";
while ((info=reader.readLine()) != null) {
System.out.println(info);
}
}
}
通过反射运行编译好的类
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class Demo02 {
public static void main(String[] args) {
try {
URL[] urls = new URL[] {new URL("file:/" + "D:/")};
URLClassLoader loader = new URLClassLoader(urls);
Class claz = loader.loadClass("HelloWorld");
Method m = claz.getDeclaredMethod("main", String[].class);
m.invoke(null, (Object)new String[]{"aa","cc"});
//由于可变参数是jdk5.0才有,不强转成Object类 上面代码会编译成m.invoke(null,"aa","cc"),发生参数个数不匹配的问题
//因此必须加上Object强转
//public static void main(String[] args)
} catch (Exception e) {
// TODO: handle exception
}
}
}