posts - 165, comments - 198, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

让 java 动态

Posted on 2007-10-09 09:26 G_G 阅读(1284) 评论(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



评论

# re: 让 java 动态   回复  更多评论   

2007-10-09 14:41 by KF.咖啡
没有看懂

# re: 让 java 动态   回复  更多评论   

2007-10-09 22:29 by Unmi
这种方法太过于原始,至少弄个像内存中编译加载执行
或者用 ASM,CGLIB,aspectj来修过字节码的也行,再就是参考BSH的实现看看。
JDK6已经提供了动态脚本支持。

# re: 让 java 动态   回复  更多评论   

2007-10-10 09:28 by G_G
@Unmi
谢谢提醒

# re: 让 java 动态   回复  更多评论   

2008-05-19 18:44 by afaf
不过 还有更好的 方法 用 Ruby

只有注册用户登录后才能发表评论。


网站导航: