Groovy 将代码添加到构造函数
Groovy 中有没有一种方法可以在实例化类时向构造函数添加代码?我有一个 Groovy 类(但我无法修改这个特定类的源代码),但我希望有一种方法可以注入代码(也许通过元类),以便我的代码作为构造函数的一部分运行(在此如果只有一个,默认构造函数)。
谢谢, 杰夫
Is there a way in Groovy that I can add code to a constructor when a class is instantiated? I have a Groovy class (but I can't modify the source of this particular one), but I was hoping there was a way to inject code (maybe via the metaclass) so my code gets run as part of the constructor (in this case there is only one, default constructor).
Thanks,
Jeff
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以重写构造函数,但这有点棘手,特别是当您重写默认构造函数时。您需要为类的
metaClass.constructor
分配一个闭包,并且该闭包应返回一个新实例。棘手的部分是,如果您调用已重写的构造函数,您将进入递归循环并生成堆栈溢出。您需要另一种方法来获取该类的实例,例如不同的构造函数。对于测试,有时可以绕过此限制。通常,首先实例化一个对象,然后重写构造函数以返回现有实例就足够了。例子:
You can override the constructor, but it's a little tricky, particularly if you're overriding the default constructor. You need to assign a closure to the class's
metaClass.constructor
, and the closure should return a new instance. The tricky part is that if you call the constructor you've overriden, you'll get into a recursive loop and generate a stack overflow. You need another way to get an instance of the class, such as a different constructor.For testing, it's sometimes possible to get around this limitation. Usually, it's enough to first instantiate an object, then override the constructor to return the existing instance. Example:
可以添加新的构造函数或替换旧的构造函数。如果您需要原始构造函数,则可以使用反射:
请注意,如果您的构造函数有参数,则必须更改此设置,例如:
PS:请注意,当您要添加尚不存在的构造函数时,请使用 < code><< 运算符改为:
MyObject.metaClass.constructor << { /* 如上 */ }
。It is possible to add new constructors or replace the old one. If you need the original constructor, you can use reflection for that:
Note that you have to change this if you have parameters to your constructors, e.g:
PS: Note that when you want to add constructors which are not yet existent, use the
<<
operator instead:MyObject.metaClass.constructor << { /* as above */ }
.您可以通过使用标准 Java 反射存储原始构造函数来绕过所提出的解决方案中的限制。例如,这就是我在 spock 测试中初始化一个类(基本注入)的方法:
它仅被调用一次,但每次有人调用构造函数时,我都会得到一个不同的实例,从而避免清理值并确保线程安全。
You can bypass the limitations in the solution proposed by storing the original constructor using standard Java reflection. For example, this is what I do initialize a class (basic injection) in a spock test:
This gets invoked only once, but eveytime someone calls a constructor I get a different instance avoiding cleaning values and ensuring thread safety.