Posted on 2007-10-09 09:26
G_G 阅读(1301)
评论(4) 编辑 收藏 所属分类:
Inspiration
在 D2D 论坛中见
一文标题
《在java中利用动态编译实现eval》
http://dev2dev.bea.com.cn/bbsdoc/20060724298.html
虽然给出代码不能运行 但标题的意思已经达到
在此 我也不多说了
在此完善下原作者的代码 并使可运行来方便大家理解
企图说明:
代码的可用性是没有的,但代码向我们打开了一个使java动态编译的一向大门
有想法的程序员们。我们在此得到了什么?
代码说明:
1.为了使用例子的方便 testJavac.java 是 Bean ( name , avg ) 也是 逻辑类 ( eval(string) )
2.运行请在 classpath 加入 java\lib\tools.jar jar 包 ( com.sun.tools.javac.Main )
3.还是方便运行本例对 自己在什么 path 并不在意 类中使用了 System.getProperty("user.dir")
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import com.sun.tools.javac.Main;
public class testJavac{
public String getName(){
return "刘凯毅";
}
public int getAvg(){
return 24;
}
public Object eval(String str)throws Exception{
//生成java文件
String s = "class Temp{";
s += "private testJavac tj = new testJavac();";
s += "public String rt(){";
s += " return \"\"+tj."+str+"();" ;
s += "}";
s +="}";
File f = new File(System.getProperty("user.dir")+"\\Temp.java");
PrintWriter pw = new PrintWriter(new FileWriter(f));
pw.println(s);
pw.close();
//动态编译
Main javac = new Main();
String[] cpargs = new String[] {"-d", System.getProperty("user.dir") ,"Temp.java"};
int status = javac.compile(cpargs);
if(status!=0){
System.out.println("没有成功编译源文件!");
return null;
}
//调用Temp的rt方法返回结果:
ClassLoader mc = this.getClass().getClassLoader();
Class clasz = mc.loadClass("Temp");
Method rt = clasz.getMethod("rt", new Class[]{});
return rt.invoke(clasz.newInstance(), new Object[] { });
//如果方法没有返回就直接调用
}
public static void main(String[]args)throws Exception{
testJavac jj = new testJavac();
System.out.println( jj.eval(args[0]) );
}
}
运行结果
D:\javac>javac -classpath D:\java\lib\tools.jar;. testJavac.java
D:\javac>java -classpath D:\java\lib\tools.jar;. testJavac getName
刘凯毅
//此时在当前目录下你可以看到 多了一个 Temp.java 和 Temp.class 文件
//再使用 CalssLoader.loadClass方法动态加载到运行环境中来
//创建 动态 加载 动态 (java 动起来了)
D:\javac>java -classpath D:\java\lib\tools.jar;. testJavac getAvg
24