[英]Adding methods to a class using Groovy in Java
I am working on a Java module that uses Groovy as a compile time dependency and I would like to add a method to my Java class Person
(Like the Groovy JDK ) without writing Groovy code. 我正在研究一个使用Groovy作为编译时依赖项的Java模块,我想在不编写Groovy代码的情况下向我的Java类
Person
(如Groovy JDK )添加一个方法。
In Groovy I would achieve it like that 在Groovy中,我会像那样实现它
Person.meta.doSomething = { String param -> println "do something: ${param}" }
How can I do it using the Groovy API form Java? 如何使用Groovy API表单Java来完成它?
EDIT 1: 编辑1:
I have implemented the following so far and I am almost there. 到目前为止我已经实现了以下内容,我几乎就在那里。 I instantiate an Expando class for
Person
and register a MethodClosure
that delegates the method call to a method in the class PersonDefaultMethods
. 我实例化在Expando类
Person
并注册MethodClosure
该委托方法调用的类中的方法PersonDefaultMethods
。
ExpandoMetaClass expando = new ExpandoMetaClass (Person.class, true, false);
expando.registerInstanceMethod ("format", new MethodClosure (new PersonDefaultMethods(), "format"));
expando.initialize ();
The PersonDefaultMethods
contains the the implementation of the methods I declared in the Expando class. PersonDefaultMethods
包含我在Expando类中声明的方法的实现。
public class PersonDefaultMethods {
public String format(String format) {
return this.toString(); // this one gets called
}
public String format(Person self, String format) { // but I want this method to be called
return self.getFirstname() + " " + self.getLastname();
}
}
When I know execute a Groovy script within this context I am able to call the format
method on a Person
instance but I am unable to access the delegate
like I usually can using a closure. 当我知道在这个上下文中执行Groovy脚本时,我能够在
Person
实例上调用format
方法,但是我无法像通常使用闭包那样访问delegate
。
EDIT 2: 编辑2:
The approach of using a closure subclass or anonymous closure class fails in my implementation. 在我的实现中,使用闭包子类或匿名闭包类的方法失败了。
ExpandoMetaClass expando = new ExpandoMetaClass(Person.class, true, false);
expando.registerInstanceMethod("format", new Closure(this) {
@Override
public Object call(Object arguments) {
return super.call(arguments);
}
@Override
public Class[] getParameterTypes () {
return new Class[] { String.class};
}
});
expando.initialize ();
This does the job. 这样做了。 Thank you.
谢谢。
You can get the current meta class via GroovySystem.getMetaClassRegistry().getMetaClass(Person.class);
您可以通过
GroovySystem.getMetaClassRegistry().getMetaClass(Person.class);
获取当前的元类GroovySystem.getMetaClassRegistry().getMetaClass(Person.class);
better. 更好。 But to simulate the above you need to do several things by hand Groovy does for you in the background.
但要模拟上述内容,您需要手动完成Groovy在后台为您做的几件事。
ExpandoMetaClass
(short EMC). ExpandoMetaClass
(短EMC)。 If the metaclass from above is not an EMC, you will need to create one and register it in the registry: ExpandoMetaClass emc = new ExpandoMetaClass(Person.class)
. ExpandoMetaClass emc = new ExpandoMetaClass(Person.class)
。 registerInstanceMethod
with either a String and Closure, or a MetaMethod. registerInstanceMethod
。 The variant above is the Closure version and will call the other one in the background. registerInstanceMethod
will be the name of the method registerInstanceMethod
的字符串将是方法的名称
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.