Java底層(二) - Java的動態編譯

在Java的動態編譯中用到了兩個Java底層類,即com.sun.tools.javac.Main和Class。javascript

用過javascript的人都知道在JS中的eval()方法特別好用,能夠動態的調用函數,可是在java中咱們要實現相似的功能,實現動態編譯該如何實現呢?java

咱們應該會想到一個簡單思路:創建一個臨時的Temp類暫時放在文件流中,而後進行編譯,而後再用java的映射獲取臨時類中的方法調用便可。函數

下面是一個例子程序:ip

import java.io.PrintWriter;
import java.lang.reflect.Method;字符串

public class JavaCT {
 
 public static void main(String args[]){
  JavaCT jc = new JavaCT();
  jc.eval("liao");
 }
 
 public void eval(String str){
  //System.out.println(System.getProperty("user.dir"));
  String s = "class Temp{";
  s += "public static String call(String[] ss){";
  s += "System.out.println(\"" + str + "\");";
  s += "return \"return str\";";
  s += "}}";
  
  try{
   java.io.File f = new java.io.File("Temp.java");
   PrintWriter pw = new PrintWriter(f);
   pw.println(s);
   pw.close();
   
   //動態編譯
   String[] commadline = {"-d",System.getProperty("user.dir"),"Temp.java"};
   int status = com.sun.tools.javac.Main.compile(commadline);
   if(status != 0) System.out.println("Faile !!!!!");
  }catch(Exception e){
   System.out.println("編譯錯誤!");
  }
  
  try {
   Class<?> cls = Class.forName("Temp");
   
   //System.out.println(ClassLoader.getSystemClassLoader().getResource("Temp.java"));
   //映射call方法
   Method call = cls.getMethod("call", new Class[]{String[].class});
   //執行call方法
   System.out.println(call.invoke(null, new Object[]{new String[0]}));
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("運行錯誤!");
  }
  
 }
}
get

經過該例子能夠知道一個類能夠經過字符串建立並執行它,那麼只須要把該程序稍微修改就能夠變成JS中相似的eval()了。咱們只須要修改Temp中的call方法便可。it

相關文章
相關標籤/搜索