动态编译的应用场景

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 any null elements.

动态编译

动态编译生成一个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进行转型。
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐