Java动态编译

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

回到顶部