一个有难度的问题——反射机制与类的定义(500分相赠)


如题:
要实现的要求是:
在运行期定义一个类的名字、属性、方法,并用反射的方式实例化这个类

请注意要求是运行期、定义

哪位大哥能给我一个思想,最好有核心代码,这100分是给大家散的,对我启发特别大的朋友另赠500分
谢谢大家

25 个解决方案

#1


很简单啊
Class c=Class.forName(className);
c.getConstructor...
c.getDeclaredMethod...
最基本的反射。。

#2


#3


简单

俺有写有一个程序:http://community.csdn.net/Expert/TopicView.asp?id=3818601



#4


java.lang.Class and java.lang.Reflect
自己看吧。

#5


在运行期定义类、属性、方法,光靠反射是无法完成
得借助代码增强的工具来做才行

#6


运行期定义应该不行的吧。
除非你自己用runtime.exec javac 来编译在用classloader加载

在运行期构建某个已有的class的话就也没有什么难度了吧。

#7


但是我看的不太明白你的意思,你说在运行期间定义,是不是运行期间更改类的结构,这样的话,估计不行。

#8


据我所知apache jakarta 的 BCEL 就是来做这个事情的,你可以参考一下,我没有用过

#9


up

#10


运行期??
刚才还没注意呢
那你的字符串怎么输入

#11


UP

#12


UP

#13


我好像贴过一个学习cglib的例子,不过找不到了 :(

#14


以前我们在讨论classloader和资源回收的时候好像涉及到过这样的问题。呵呵。

import java.net.*;
import java.io.*;
import java.lang.reflect.*;
/** 
 * class to test class reloading 
 */
public class CLTest{
public static void main(String[] args) {
String cs = "public class Foo { public static int getNum(){ int tmp = 666;System.out.println(\"value is \"+tmp);return tmp;}}";
int i = 100;
Runtime r = Runtime.getRuntime();
try {
// loop until we press enter 
while (System.in.available() == 0) {
modifyClass(cs,i);
int ires = execClass();
System.out.println("ires="+ires);
i+=100;
r.gc();
System.out.println(" free mem: "+ r.freeMemory() + " of " + r.totalMemory());
}
} catch (Exception e){
System.out.println(e);
System.exit(0);
}
}
// replace the 666 in the code argument with the number i
// write it as file Foo.Java and compile it
public static void modifyClass(String code, int i) {
Runtime r = Runtime.getRuntime();
BufferedWriter writer;
File foo=new File("E:\\tmp\\Foo.java");
foo.delete();
String newcode = code.replaceFirst("666",""+i);
try {
writer = new BufferedWriter(new FileWriter(foo,false));
writer.write(newcode,0,newcode.length());
writer.close();
//System.out.println("Written ..."+newcode);
Process p =r.exec("javac E:\\tmp\\Foo.java");
p.waitFor();
System.out.println("compile complete");
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
// get a new class loader, load the class and run the getNum method
public static int execClass() {
Object res=null;
try {
URLClassLoader cl;
URL[] urls = {new File("E:\\tmp/").toURL()};
cl = new URLClassLoader(urls);
Class c = cl.loadClass("Foo");
Method m = c.getMethod("getNum",null);
res = m.invoke (null,null);c=null;
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
return ((Integer)res).intValue();
}
}

#15


“在运行期定义”似乎不是一个很好的主意,其涉及到要在运行期间编译一个新的类。
楼主的问题不能用其它的方法解决??

#16


在系统启动时,各个控制类需要创建,各线程、各模块需要初始化。在系统关闭时,尚在处理的任务必须存储,各模块占用的线程将先后释放。我们设计由一个主控类开控制系统的启动和关闭。
使用的是这种技术

#17


我现在搞的项目是这个:把源代码给老兄看看,还没有完工


public class SubSystemController
    extends java.lang.Thread {

    /**
     * SubSystemController:初始化内部的句柄注册集合
     */
    private SubSystemController() {
    }

    /**
     * 实例化本类的一个对象
     */
    static SubSystemController sub = new SubSystemController();

    /**
     * 用于存储各个模块实例的模板
     */
    public static java.util.HashMap moduleLib = new java.util.HashMap();

    /**
     * 是否在运行
     */
    public static boolean isRun;

    /**
     * 是否停止
     */
    public static boolean stop = false;

    public static SubSystemController getInstance() {
        return sub;
    }

    /**
     * startSS 启动系统
     * <p>Process:启动子系统,创建各个控制类,初始化各线程、各模块
     * <br>并注册它们的句柄</p>
     */
    public void startSS() {
        this.isRun = true;
        System.out.println("System start!");
        /**
         * 初始化各个模块
         */
        ConfigManager configManager = new ConfigManager();
        ObjectGettingManager objectGettingManager = new
            ObjectGettingManager();
        AlarmStatusManager alarmStatusManager = new AlarmStatusManager();
        AlarmAnalyser alarmAnalyser = new AlarmAnalyser();
        TicketCreator ticketCreator = new TicketCreator();
        AnounceContentGenerator anounceContentGenerator = new
            AnounceContentGenerator();

        /**
         * 注册各个模块的句柄
         */
        moduleLib.put("configManager", configManager);
        moduleLib.put("objectGettingManager", objectGettingManager);
        moduleLib.put("alarmStatusManager", alarmStatusManager);
        moduleLib.put("ticketCreator", ticketCreator);
        moduleLib.put("alarmAnalyser", alarmAnalyser);
        moduleLib.put("anounceContentGenerator", anounceContentGenerator);
        try {
            /**
             * AlarmAnalyser开始轮询
             */
        }
        catch (Exception e) {
            /**
             * Error Handling
             */
        }
    }

    /**
     * shutoffSS 关闭子系统
     * <p>Process:在系统关闭时,各模块占用的线程将先后释放,尚在处理的任务必须存储;
     */
    public void shutoffSS() {

        moduleLib.remove("configManager");
        moduleLib.remove("objectGettingManager");
        moduleLib.remove("alarmStatusManager");
        moduleLib.remove("ticketCreator");
        moduleLib.remove("alarmAnalyser");
        moduleLib.remove("anounceContentGenerator");
        stop = true;
        try {
            //Thread.yield();
        }
        catch (Exception ex) {
        }

    }

    /**
     * run:运行期方法,保持单独的线程,定时打印时间。
     */
    public void run() {
        this.isRun = true;
//        while (stop == false) {
//            try {
//                Thread.sleep(2000) ;
//                System.out.println(new java.util.Date()) ;
//            }
//            catch (Exception e) {
//                e.printStackTrace() ;
//            }
//        }
        System.out.println("System shut off!");
    }
}

#18


谢谢各位,大家贴的代码我会好好看一下的,
有的朋友还没有了解我的意思,其实很简单

就是说一个类本来是不存在的,只是我需要的时候才定义他.

我认为反射机制是可以解决这个问题的,当然还需要classloader的配合,有没有兄弟又跟好的建议??

#19


最顶楼的几个兄弟是没有理解我的意思的,最简单的反射我当然理解,要是真的有这么简单,我也不会拿500分出来了

#20


一种笨的方法是用字符串生成对象,然后调用当地javac编译器动态编译,然后用Reflection调用。。。

另一种方法是采用类似Dynamic Proxy那样的东西,实现InvocationHandler

#21


也参考

Janino
http://www.janino.net/

#22


to: taglib(温习中) 
你是说的代理模式吧,我也想过这种方式,但好像不行,能不能在说得具体点??

#23


to : jiangxuhong217(红红) 

说实话,我没有找到你是在源程序中的哪里定义的一个类,能否指明?

#24


楼主去看看javassist,里面就有一个动态生成class的例子

#25


参考BeanShell的做法
http://www.beanshell.org

或ASM 
http://asm.objectweb.org
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告