| 
         
     
     | 
     | 
    
  
    | 
    在java中利用动态编译实现eval | 
   
  
     | 
   
  
     | 
   
  
    | 
     作者:未知  来源:月光软件站  加入时间:2005-2-28 月光软件站  | 
   
  
    我们知道,在很多脚本语言中都有eval涵数,它可以把字符串转换为表态式并执行.如在javaScript中
  var str = aid.value + ".style.top = 10;"
  把一个id为"aid"的控制的值取出来加合并成一个字符串,如果aid的值是"axman",则 str = "axman.style.top = 10" 现在我们要让控制axman移动到顶部为10的位置:
  eval(str);
  这样这个字符串就变成了表达式或语句开始执行.这样的功能对于动态构造变量是有非常重要的 意义.
  那么在java中,如果实现这个功能呢?其实我们可以用动态编译来实现:
  假设有一组方法实现不同的功能,现在要根据传进来的方法名调用相应的方法,假如没有eval功能,我们 只能这么做:
 
 
  MyClass mc = new MyClass(); if(str.equals("m1"))    mc.m1(); else if(str.equals("m1"))    mc.m2(); else if(str.equals("m3"))    mc.m3();  else if(.........)    .........();
  如果有一百种情况呢?
  如果我们用eval方法就可以直接这样:
  String str = ...........; eval("mc"+str+"();");
  是不是非常方便?关键是如何实现eval()?
  我们把要转换的字符串构造一个完整的类:如果方法是有返回值的.则:
  public Object eval(String str){    //生成java文件    String s = "class Temp{"; s += "Object rt(){" s += "MyClass mc = new MyClass();"         s += " return mc."+str+"();";         s += "}" s +="}";    File f = new File("Temp.java");    PrintWriter pw = new PrintWriter(new FileWriter(f));    pw.println(s);    pw.close();    //动态编译    com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();    String[] cpargs = new String[] {"-d", "所在目录","Temp.java"};    int status = javac.compile(cpargs);    if(status!=0){       System.out.println("没有成功编译源文件!");       return null;    }    //调用Temp的rt方法返回结果:    MyClassLoader mc = new MyClassLoader();    Class clasz = mc.loadClass("Test.class",true);    Method rt = clasz.getMethod("rt", new Class[]{ String[].class });    return rt.invoke(null, new Object[] { new String[0] });    //如果方法没有返回就直接调用 }
  我们可以先写好多个重载的eval,有返回值和没有返回值的.以及可以传递参数的.
  这样我们就可以用字符串转换为java的语句来执行.
  本文只是一个例子,说明了一个动态编译的思想,更好的实现请各位朋友自己来完成.
  
 
  | 
   
  
     | 
   
  
     相关文章:相关软件:  | 
   
   
      |