首页 文章

在Java中使用Groovy向类添加方法

提问于
浏览
4

我正在研究一个使用Groovy作为编译时依赖项的Java模块,我想在不编写Groovy代码的情况下向我的Java类 Person (如Groovy JDK)添加一个方法 .

在Groovy中,我会像那样实现它

Person.meta.doSomething = { String param -> println "do something: ${param}" }

如何使用Groovy API表单Java来完成它?

EDIT 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();
    }
}

当我知道在此上下文中执行Groovy脚本时,我能够在 Person 实例上调用 format 方法但我无法访问 delegate ,就像我通常可以使用闭包一样 .

EDIT 2:

在我的实现中,使用闭包子类或匿名闭包类的方法失败了 .

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 ();

这样做了 . 谢谢 .

1 回答

  • 2

    您可以通过 GroovySystem.getMetaClassRegistry().getMetaClass(Person.class); 更好地获取当前元类 . 但要模拟上述内容,您需要手动完成Groovy在后台为您做的几件事 .

    • 首先,您需要一个 ExpandoMetaClass (短EMC) . 如果上面的元类不是EMC,则需要创建一个并在注册表中注册它: ExpandoMetaClass emc = new ExpandoMetaClass(Person.class) .

    • 接下来,您需要使用String和Closure或MetaMethod调用 registerInstanceMethod . 上面的变体是Closure版本,将在后台调用另一个版本 .

    • 要遵循Groovy约定,您需要使用您想要方法的签名的doCall方法创建一个Closure子类(可能是匿名的) . registerInstanceMethod 的字符串将是方法的名称

    • 您当然也可以利用其中一个现有的MetaMethod子类(或您自己的子类)来实现目标 .

相关问题