在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