动态编译 JAVA 6.0引入了动态编译机制。
动态编译的应用场景 可以做一个浏览器端编写java代码,上传服务器编译和运行的在线评测 系统。
服务器动态加载某些类文件进行编译。
动态编译的两种做法 通过Runtime
调用javac
,启动新的进程去操作。
通过JavaCompiler
动态编译。
JavaCompiler:
JavaCompiler.run(…):
int run(InputStream in, OutputStream out, OutputStream err, String… arguments);
第一个参数:为java编译器提供参数 输入: null 表示System.in
第二个参数:得到 Java 编译器的输出信息 : null 表示System.out
第三个参数:接收编译器的 错误信息: null 表示System.err
第四个参数:可变参数(是一个String数组)能传入一个或多个 Java 源文件
返回值:0表示编译成功,非0表示编译失败
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import javax.tools.JavaCompiler;import javax.tools.ToolProvider;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class TestDynamic { public static void main (String[] args) throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int run = compiler.run(null , null , null , "F:\\java\\base\\DynamicCompille\\src\\hello.java" ); System.out.println(run == 0 ?"编译成功" :"编译失败" ); Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("java -cp F:\\java\\base\\DynamicCompille\\src hello" ); InputStream inputStream = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String info = "" ; while ((info = reader.readLine()) != null ){ System.out.println(info); } } }
编译成功 hello!!!
通过反射运行编译好的类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Test public void TestReflect () { try { URL[] uRls = new URL[]{new URL("file:/" +"F:/java/base/DynamicCompille/src/" )}; URLClassLoader loader = new URLClassLoader(uRls); Class clazz = loader.loadClass("hello" ); Method m = clazz.getMethod("main" , String[].class); m.invoke(null , (Object)new String[]{}); } catch (Exception e) { e.printStackTrace(); } }
hello!!!
同样可以执行。
脚本引擎 JAVA脚本引擎是从JDK6.0之后添加的新功能。
脚本引擎介绍:使得 Java 应用程序可以通过一套固定的接口与各种脚本引擎交互,从而达到在 Java 平台上调用各种脚本语言的目的。
Java 脚本 API 是连通 Java 平台和脚本语言的桥梁。可以把一些复杂异变的业务逻辑交给脚本语言处理,这又大大提高了 开发效率。
脚本引擎执行JavaScript代码 获取脚本程序输入,通过脚本引擎运行脚本并返回运行结果,这是最核心的接口。
Rhino
是一种使用 Java 语言编写的 JavaScript
的开源实现,原先由Mozilla
开发 ,现在被集成进入JDK 6.0
。
通过脚本引擎的运行上下文在脚本和 Java 平台间交换数据,通过 Java 应用程序调用脚本函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine engine = scriptEngineManager.getEngineByName("javascript" ); engine.put("msg" , "you see you , one day day de" ); String str = "var user = { name: 'jack', age:18, schools:['北京交通大学','计算机与信息技术学院']};" ; str+="print(user.name);" ; engine.eval(str); System.out.println(engine.get("msg" )); engine.eval("msg = 'day by day';" ); System.out.println(engine.get("msg" ));
jack you see you , one day day de day by day
脚本引擎执行JavaScript函数 1 2 3 4 5 6 7 8 9 engine.eval( "function add(a, b){ var sum = a+b; return sum;}" ); Invocable jsInvoke = (Invocable)engine; Object add = jsInvoke.invokeFunction("add" , new Object[]{13 , 44 }); System.out.println(add);
交换数据 1 2 3 4 5 6 7 String jsCode = " var list = java.util.Arrays.asList([\"北京交通大学\",\"计算机与信息技术学院\"]);" ; engine.eval(jsCode); List<String> list = (List) engine.get("list" ); for (String t: list){ System.out.println(t); }
脚本引擎执行js文件 a.js:
1 2 3 4 5 6 7 8 9 10 function test ( ) { var a = 3 ; var b =4 ; print("invoke js file:" + (a+b)); } test()
1 2 3 4 5 InputStream resource = testengine.class.getClassLoader().getResourceAsStream("a.js" ); BufferedReader br = new BufferedReader(new InputStreamReader(resource)); engine.eval(br); br.close();
invoke js file: 7