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

说好不能打脸
Java领域优质创作者
博客专家认证
2005-03-11 04:45:36
如题:
要实现的要求是:
在运行期定义一个类的名字、属性、方法,并用反射的方式实例化这个类

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

哪位大哥能给我一个思想,最好有核心代码,这100分是给大家散的,对我启发特别大的朋友另赠500分
谢谢大家
...全文
265 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
taglib 2005-03-12
  • 打赏
  • 举报
回复
参考BeanShell的做法
http://www.beanshell.org

或ASM
http://asm.objectweb.org
zcjl 2005-03-12
  • 打赏
  • 举报
回复
楼主去看看javassist,里面就有一个动态生成class的例子
说好不能打脸 2005-03-12
  • 打赏
  • 举报
回复
to : jiangxuhong217(红红)

说实话,我没有找到你是在源程序中的哪里定义的一个类,能否指明?
说好不能打脸 2005-03-12
  • 打赏
  • 举报
回复
to: taglib(温习中)
你是说的代理模式吧,我也想过这种方式,但好像不行,能不能在说得具体点??
taglib 2005-03-12
  • 打赏
  • 举报
回复
也参考

Janino
http://www.janino.net/
taglib 2005-03-12
  • 打赏
  • 举报
回复
一种笨的方法是用字符串生成对象,然后调用当地javac编译器动态编译,然后用Reflection调用。。。

另一种方法是采用类似Dynamic Proxy那样的东西,实现InvocationHandler
说好不能打脸 2005-03-12
  • 打赏
  • 举报
回复
最顶楼的几个兄弟是没有理解我的意思的,最简单的反射我当然理解,要是真的有这么简单,我也不会拿500分出来了
说好不能打脸 2005-03-12
  • 打赏
  • 举报
回复
谢谢各位,大家贴的代码我会好好看一下的,
有的朋友还没有了解我的意思,其实很简单

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

我认为反射机制是可以解决这个问题的,当然还需要classloader的配合,有没有兄弟又跟好的建议??
jiangxuhong217 2005-03-11
  • 打赏
  • 举报
回复
我现在搞的项目是这个:把源代码给老兄看看,还没有完工


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!");
}
}
jiangxuhong217 2005-03-11
  • 打赏
  • 举报
回复
在系统启动时,各个控制类需要创建,各线程、各模块需要初始化。在系统关闭时,尚在处理的任务必须存储,各模块占用的线程将先后释放。我们设计由一个主控类开控制系统的启动和关闭。
使用的是这种技术
Hodex 2005-03-11
  • 打赏
  • 举报
回复
“在运行期定义”似乎不是一个很好的主意,其涉及到要在运行期间编译一个新的类。
楼主的问题不能用其它的方法解决??
takecare 2005-03-11
  • 打赏
  • 举报
回复
以前我们在讨论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();
}
}
zcjl 2005-03-11
  • 打赏
  • 举报
回复
我好像贴过一个学习cglib的例子,不过找不到了 :(
hero_zhoor 2005-03-11
  • 打赏
  • 举报
回复
UP
hero_zhoor 2005-03-11
  • 打赏
  • 举报
回复
UP
jFresH_MaN 2005-03-11
  • 打赏
  • 举报
回复
运行期??
刚才还没注意呢
那你的字符串怎么输入
BasaraTracy 2005-03-11
  • 打赏
  • 举报
回复
up
wuyue-tiger 2005-03-11
  • 打赏
  • 举报
回复
据我所知apache jakarta 的 BCEL 就是来做这个事情的,你可以参考一下,我没有用过
icebluenet 2005-03-11
  • 打赏
  • 举报
回复
但是我看的不太明白你的意思,你说在运行期间定义,是不是运行期间更改类的结构,这样的话,估计不行。
takecare 2005-03-11
  • 打赏
  • 举报
回复
运行期定义应该不行的吧。
除非你自己用runtime.exec javac 来编译在用classloader加载

在运行期构建某个已有的class的话就也没有什么难度了吧。
加载更多回复(5)

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧