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

时间:2012-02-28 19:20:27

标签: groovy

使用闭包映射在Groovy中实现接口时(如在http://groovy.codehaus.org/Groovy+way+to+implement+interfaces中)有没有办法在使用as关键字或asType方法实现接口后将对象转换回映射?

2 个答案:

答案 0 :(得分:6)

根据您的用例,您似乎可以在将其转换为所需界面之前保留对原始Map的引用。

但是,查看将Map对象转换为接口的源代码(使用Proxy),看起来您可以通过获取{{1来重新检索原始地图代表。

InvocationHandler

注意:这取决于Groovy代码的内部,因此使用风险由您自行承担:

答案 1 :(得分:2)

有趣的问题......简短的回答,没有。答案很长,也许......假设你有类似的东西:

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 ]

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

您感兴趣的用例是什么?