sla*_*ery 57 java reflection code-generation javassist
一个类可以在运行时向自己添加一个方法(比如从一个static块),这样如果有人在这个类上执行反射,他们会看到新方法,即使它没有在编译时定义?
背景:
我正在使用的框架要求按惯例Action定义具有doAction(...)方法的类.框架在运行时检查这些类,以查看其doAction()方法中可用的参数类型.例如:doAction(String a,Integer b)
我希望每个类能够以编程方式生成doAction()具有各种参数的方法,并在检查时及时生成.方法的主体可以是空的.
And*_*s_D 55
这并不简单.类加载器加载类后,无法更改加载类的方法.当请求类时,类加载器将加载它并链接它.而且(使用Java)无法更改链接代码或添加/删除方法.
我想到的唯一技巧就是玩类加载器.如果我们删除自定义类加载器,那么该类加载器加载的类也应该被删除或不可访问.我想到的想法是
我把它留作思考的食物,不能证明,如果这导致解决方案或我们有陷阱.
作为问题的简单答案:不,我们无法更改已加载的类,就像我们可以使用反射更改字段的内容一样.(我们也不能添加或删除字段).
小智 23
Andres_D是对的,我们可以使用自定义类加载这么做,这里有一个如何执行此操作的详细指南:http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.页面= 1 HTML?
本文介绍了如何编写动态Java代码.它讨论了运行时源代码编译,类重新加载以及使用代理设计模式来修改对其调用者透明的动态类.
事实上,奥地利的研究人员编写了一个JVM,甚至允许重新加载具有不同类型层次结构的类.他们通过使用现有的线程保存点来生成对象及其所有相关引用和引用内容的完整"侧面Universe",然后一旦完全重新调整所有必需的更改,只需交换所有更改的类即可实现此目的.[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#热插拔
我不确定它是否是第一个,但是2001年Sun员工的论文似乎是提到HotSpot到Hot Swap功能的早期提案之一.[2]
参考
[1]T.Würthinger,C.Wimmer和L. Stadler,"Java的动态代码演化",在2010年维也纳举行的第八届Java编程原理与实践国际会议上发表.
[2] M. Dmitriev,"迈向Java语言应用程序运行时演化的灵活和安全技术",在OOPSLA工程复杂面向对象系统进化研讨会,2001年.
不,在Java中不可能(轻松)实现。
听起来好像您在尝试使用Java,就像它是一种动态编程语言一样。例如,Ruby具有开放类:您可以在运行时从Ruby类中添加和删除方法。在Ruby中,您的类中也可以有一个“缺少方法”的方法,当您尝试调用该类中不存在的方法时,该方法将被调用。Java中也不存在这样的东西。
有一个在JVM上运行的Ruby版本,即JRuby,它必须执行非常困难的技巧才能使开放类在JVM上工作。