使用闭包映射在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 ]
但是,由于这是一个映射,任何包含多个具有相同名称和不同参数的方法的类都将失败。我也不确定在第一种情况下这样做有多明智。。。
出于兴趣,您的用例是什么?