有没有什么办法可以在运行时将新的方法和属性注入到类中。
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html我们可以通过使用Groovy来做到这一点。
只使用Java吗?
答案 0 :(得分:10)
是否可以通过使用来实现 爪哇?
简单的回答是强调“你不想那样做!”。
这在技术上是可行的,但并非没有采用极其复杂,昂贵且脆弱的技巧,如字节码修改 1 。即便如此,您还必须依靠动态加载来访问修改后的类型和(可能)反射以利用其新成员。简而言之,你会为自己创造很多痛苦,只要获得很少的收益。
Java是一种静态类型语言,添加/修改类类型签名可能会破坏类的静态类型合约。
1 - AspectJ等允许您向类中注入其他行为,但它可能不是您所追求的“运行时”注入。当然,注入的方法不能用于静态编译的代码来调用。
答案 1 :(得分:1)
所以,如果你真的疯了,你可以做一些像他们勾勒出来的here。你可以做的是加载.java文件,找到正确的插入点,添加你需要的任何方法,调用java编译器并重新加载类。祝你好好调试那个烂摊子:))
编辑 This实际上可能会有用......
答案 2 :(得分:1)
只使用Java吗?
很明显,你要做的“唯一”事情就是定义一个instrumentation agent来提供适当的ClassFileTransformer
,你必须使用反射来调用添加的方法。可能这不是你想要做的事情,但它是可行的,并且有一个明确定义的界面。如果您想修改现有方法,可能会对AspectJ等内容感兴趣。
答案 3 :(得分:1)
你可以用AOP做一些非常时髦的事情,虽然在运行时真正修改类是一种非常多毛的技术,需要大量的类加载魔法和手法。
更容易的是使用AOP技术生成目标类的子类并将新方法引入其中,而AOP称为“mixin”或“introduction”。请参阅here以了解Spring AOP如何做到这一点,尽管与您实际尝试实现的目标相比,这可能相当蹩脚。
答案 4 :(得分:0)
虽然有可能,但它没用。
您将如何访问这些新字段和方法?
您无法直接使用这些方法和字段(作为“普通”字段和方法),因为它们不会被编译。
如果你想要的是添加“属性”和“方法”的可能性,你可以使用Map<String, Object>
作为“动态属性”,使用Map<String, SuitableInterface>
作为“动态方法”,并按名称查看它们。
如果您需要Java的扩展语言,可以添加嵌入式动态语言(如Javascript或Groovy);其中大多数都可以访问任意java对象和方法。