Groovy 元类与 Java 8 的互操作性

Posted

技术标签:

【中文标题】Groovy 元类与 Java 8 的互操作性【英文标题】:Groovy meta class interoperability with Java 8 【发布时间】:2014-05-10 09:12:54 【问题描述】:

简介:

我正在开发一个名为awaitility 的Java 库,它也有一个Groovy 扩展。在 Java 8 之前,您可以像这样使用该库:

// Syntax example with the Groovy extension
await().atMost(500, MILLISECONDS).until  asynch.getValue() == 2 

Groovy 扩展使用在 Java API 中定义的名为 ConditionFactory 的类。但是这个 API 并没有定义一个直到方法,它接受一个 Groovy 闭包的实例。因此,该方法被添加了一个像这样的元类:

ConditionFactory.metaClass.until  Closure closure ->
      delegate.until(new Callable<Boolean>() 
        Boolean call() 
          return closure.call();
        
      );
    

如您所见,它只是委托给 Java API 中的 until 方法,该方法采用 Callable&lt;Boolean&gt; 的实例。

问题:

Java API 还包含until 的重载方法,该方法将Runnable 作为其参数。当 Groovy 扩展与 Java 8 一起使用时,将调用 until 方法的 Runnable 版本,而不是使用 Closure 作为参数的 until 方法(使用 metaClass 定义的方法)。似乎 metaClass 不再起作用了。这是为什么呢?有解决办法吗?

【问题讨论】:

野蛮假设:Closure 不是@FunctionalInterface?它的原型是什么? Closure 不是一个函数式接口,但现在我仔细观察它确实实现了 Runnable!我想这可能是问题所在。 【参考方案1】:

实际上,我认为这与 Java 8 没有任何关系(很抱歉造成混淆)。我的问题的解决方法如下所示:

def originalMethod = ConditionFactory.metaClass.getMetaMethod("until", Runnable.class)
ConditionFactory.metaClass.until  Runnable runnable ->
  if (runnable instanceof Closure) 
    delegate.until(new Callable<Boolean>() 
      Boolean call() 
        return (runnable as Closure).call();
      
    );
   else 
    originalMethod.invoke(delegate, runnable)
  

【讨论】:

以上是关于Groovy 元类与 Java 8 的互操作性的主要内容,如果未能解决你的问题,请参考以下文章

Groovy:为接口委托元类?

如何在 Groovy 类中“隐藏”元类属性

如何使用 Spring boot 将 Groovy 类与 java 类一起运行

groovy语法

在 Groovy 中,实例的元类与其类的元类有啥区别

Grails 和 Groovy 元类包名称约定