我正在研究将Groovy用作编译时间依赖项的Java模块,并且希望在不编写Groovy代码的情况下向我的Java类Person
(如Groovy JDK)添加一个方法。在Java中使用Groovy添加方法
在Groovy我我该怎么办使用Groovy的API形式的Java它将实现它像
Person.meta.doSomething = { String param -> println "do something: ${param}" }
?
编辑1:
我已实施至今下面,我几乎没有。我为Person
实例化一个Expando类,并注册一个MethodClosure
,该方法调用委托给类PersonDefaultMethods
中的方法。
ExpandoMetaClass expando = new ExpandoMetaClass (Person.class, true, false);
expando.registerInstanceMethod ("format", new MethodClosure (new PersonDefaultMethods(), "format"));
expando.initialize();
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();
}
}
当我知道这种情况下我能够调用format
方法上Person
实例中执行Groovy脚本,但我无法访问delegate
像我平时可以使用封闭。
编辑2:
使用封闭子类或匿名closure类的方法我在执行失败。
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();
这样做的工作。谢谢。
即使你可以得到这个工作,是不是你的代码最终会被查找和注册表调用混乱? Java不适合这种实例扩展。因此Groovy –
我绝对同意你的看法。我尝试使用这种方法的唯一原因是我的公司使用Eclipse(不提供Groovy支持),如果我开始将Groovy类放入其工作空间中,该项目将不再生成...我知道这是一个糟糕的情况,但我不能改变它(还)。 – saw303
re:“无法访问委托”。在MethodClosure中,委托/所有者用于方法调用,在这里是PersonDefaultMethods,所以它不会像这样工作。你将需要一个Closure子类。 – blackdrag