在Groovy中使用闭包映射实现接口(就像在http://groovy.codehaus.org/Groovy+way+to+implement+interfaces中一样)时,在使用as关键字或asType方法实现接口之后,有没有办法将对象转换回映射?
发布于 2012-02-29 22:50:12
根据您的用例,在将其转换为所需的接口之前,您似乎可以只保留对原始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代码的内部结构,因此使用风险自负:
发布于 2012-02-28 19:58:12
有趣的问题..。简而言之,不是。答案很长,也许...假设你有这样的东西:
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 ]
然而,因为这是一个映射,任何包含多个同名不同参数的方法的类都会失败。我也不确定在第一种情况下这样做是否明智……
出于兴趣,你的用例是什么?
https://stackoverflow.com/questions/9488277
复制相似问题