将实现接口的Groovy映射转换回映射



使用闭包映射在Groovy中实现接口时(如http://groovy.codehaus.org/Groovy+方法+到+实现+接口)在使用as关键字或asType方法实现接口后,有没有任何方法可以将对象转换回映射?

根据您的用例,在将原始Map转换为所需的接口之前,您似乎只需要保留对它的引用。

但是,查看将Map对象转换为接口(使用Proxy)的源代码,您似乎可以通过获取InvocationHandler的委托来重新检索原始映射。

def i = 1
def m = [ hasNext:{ true }, next:{ i++ } ]
Iterator iter = m as Iterator
def d = java.lang.reflect.Proxy.getInvocationHandler(iter).delegate
assert d.is(m)

注意:这取决于Groovy代码的内部,因此使用风险自负:

有趣的问题。。。简短的回答,没有。漫长的回答,也许。。。假设你有这样的东西:

def i = 1
Iterator iter = [ hasNext:{ true }, next:{ i++ } ] as Iterator

然后调用

println iter.take( 3 ).collect()

打印[1,2,3]

现在,您可以声明一个方法来实现这一点:

def mapFromInterface( Object o, Class... clz ) {
  // Get a Set of all methods across the array of classes clz
  Set methods = clz*.methods.flatten()
  // Then, for each of these
  methods.collectEntries {
    // create a map entry with the name of the method as the key
    // and a closure which invokes the method as a value
    [ (it.name): { Object... args ->
                   o.metaClass.pickMethod( it.name, it.parameterTypes ).invoke( o, args )
    } ]
  }
}

这样你就可以做:

def map = mapFromInterface( iter, Iterator )

呼叫:

println map.next()
println map.next()

将打印4,然后打印5

println map打印地图给出:

[ remove:ConsoleScript43$_mapFromInterface_closure3_closure4@57752bea,
  hasNext:ConsoleScript43$_mapFromInterface_closure3_closure4@4d963c81,
  next:ConsoleScript43$_mapFromInterface_closure3_closure4@425e60f2 ]

但是,由于这是一个映射,任何包含多个具有相同名称和不同参数的方法的类都将失败。我也不确定在第一种情况下这样做有多明智。。。

出于兴趣,您的用例是什么?

最新更新