一个类是否可以在运行时给自己添加一个方法(就像从static
块中),这样如果有人在这个类上执行反射,他们就会看到新的方法,即使它不是在编译时定义的?
背景:
按照约定,我正在使用的一个框架要求定义具有doAction(...)
方法的Action
类。框架在运行时检查这些类,以查看它们的doAction()
方法中有哪些类型的参数。例如:整数a,整数 b)
我希望每个类都能够以编程方式生成带有各种参数的doAction()
方法,并在被检查时及时生成。方法体可以为空。
发布于 2011-07-13 22:53:32
这并不简单。一旦类加载器加载了类,就无法更改加载的类的方法。当一个类被请求时,一个类加载器将加载它并链接它。而且(使用Java)无法更改链接的代码或添加/删除方法。
我脑海中浮现的唯一技巧就是玩类加载器。如果我们删除一个自定义的类加载器,那么由该类加载器加载的类也应该被删除或无法访问。我脑中浮现的想法是
<代码>G211
我将其作为思考的食粮,无法证明这是否导致了解决方案,或者我们是否存在陷阱。
作为对这个问题的简单回答:不,我们不能改变一个加载的类,就像我们可以用反射改变字段的内容一样。(我们也不能添加或删除字段)。
发布于 2012-09-15 07:26:58
Andres_D是对的,我们可以使用自定义类加载很好地做到这一点,这里有一个关于如何做到这一点的详细指南:http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=1
这篇文章解释了如何编写动态
代码。它讨论了运行时源代码编译、类重新加载,以及如何使用Proxy设计模式使对动态类的修改对其调用者透明。
事实上,奥地利的研究人员已经编写了一个JVM,它甚至允许重新加载具有不同类型层次结构的类。他们已经实现了这一点,使用现有的线程保存点来生成对象及其所有相关引用和引用内容的完整“侧面世界”,然后在完全重新洗牌所有所需的更改后,只需交换所有更改的类。1这里有一个到他们的项目http://ssw.jku.at/dcevm/的链接,oracle的赞助肯定会引起对未来计划的有趣猜测。
使用java 1.4中引入的JPDA的热交换功能,在标准Java VM中已经可以对方法体和字段进行侵入性较小的更改:
docs.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap
我不确定这是否是第一个,但这位Sun员工2001年的论文似乎是提到HotSpot到热插拔功能的早期提案之一。2
参考
1T.Würthinger,C.Wimmer和L.Stadler,“Java的动态代码演变”,2010年在维也纳举行的第8届国际Java编程原则和实践会议上发表。
2 M.Dmitriev,“走向灵活和安全的java语言应用程序运行时演化技术”,OOPSLA Engineering on Engineering Complex Object-Oriented Systems for Dmitriev,2001。
https://stackoverflow.com/questions/6680674
复制相似问题