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

相关文章
相关标签/搜索