Java动态编译
Java从jdk6.0开始引入了动态编译机制
动态编译引用场景:
- 可以做一个浏览器端编写java代码,上传服务器和运行的在线评测系统
- 服务器动态加载某些类文件进行编译
动态编译做法:
- 通过 Runtime调用javac 启动新的进程去操作
- 通过JavaCompiler进行动态编译
--通过反射编运行编译好的类
示例 1 通过Runtime调用javac 启动新的进程去操作
package compiler;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 RuntimeTest {
public static void main(String[] args) throws IOException {
Runtime run = Runtime.getRuntime(); // 获取runtime对象
Process process = run.exec("java -cp e:/szw/myjava");// 编译
InputStream in = process.getInputStream(); // 根据process后去输入流,用于打印输出到控制台
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String info = "";
while ((info = reader.readLine()) != null) {
System.out.println(info);
}
}
}
示例二 通过JavaCompiler进行动态编译
package compiler;import javax.tools.JavaCompiler;
import javax.tools.Tool;
import javax.tools.ToolProvider;
public class CompilerTest {
public static void main(String[] args) {
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
int flg = jc.run(null, null, null, "e:/szw/myjava.java");// 返回int 如果是0编译成功其他编译失败
// 第一个参数:为java编译器提供参数
// 第二个参数:得到java编译器的输出信息
// 第三个参数:接受编译器的错误信息
// 第四个参数:可变参数(是一个String数组)能传入一个或多个java源文件
// 返回值:0表示编译成功,非0表示编译失败
System.out.println(flg == 0 ? "编译成功" : "编译失败");
}
}
--通过反射编运行编译好的类
package compiler;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
public class UrlClassL {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException,
SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
URL[] url = new URL[] { new URL("file:/" + "e:/szw/") };
URLClassLoader loader = new URLClassLoader(url);
// 调用类加载的main方法
Class c = loader.loadClass("myjava");
Method method = c.getMethod("main", String[].class);
method.invoke(null, (Object) new String[] { "b", "c" });// 因为main方法是静态方法,不需要对象,所以可以为空
// 传参时,将String数组转为 object ,如果不转,编译器会把 它变成这样的一个调用 invoke(null,"b","c")
// 以多个参数的形式传入,会报错,因此必须要加上
}
}
以上是 Java动态编译 的全部内容, 来源链接: utcz.com/z/394477.html