动态编译 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);         }     } } 
编译成功
通过反射运行编译好的类 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
脚本引擎执行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