【问题标题】:Groovy meta class interoperability with Java 8Groovy 元类与 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!我想这可能是问题所在。

标签: java groovy java-8 metaclass


【解决方案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)
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多