2012-02-28 48 views

回答

6

根據您的使用情況,似乎您可以在將其轉換爲所需的界面之前保留對原始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的代碼的內部風險自負所以要用:

+0

+1輝煌:-)我沒想到那! – 2012-03-01 09:16:02

2

有趣的問題...簡短的回答,沒有。長的答案,也許......假設你有這樣的事情:

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

然後調用

println iter.take(3).collect() 

Prints立即[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() 

將打印隨後5

打印地圖println map4給出:

[ remove:[email protected], 
    hasNext:[email protected], 
    next:[email protected] ] 

然而,因爲這是一個地圖,任何包含th的多個方法的類相同的名稱和不同的參數將會失敗。我也不確定在第一種情況下做這件事是多麼明智......

您的興趣愛好是什麼?

+0

我使用Groovy很多關於編寫單元測試Java代碼和經常使用封閉的地圖一樣快和骯髒的方式來存留我的測試單元所依賴的接口(因爲我發現它比大多數嘲諷庫更容易,當我不真正關心驗證交互時)。有時我想設置一個「prototype」stubbed界面,只是稍微調整它以適應不同的測試場景,但如果不能將其轉換回地圖,我就無法做到這一點。 – 2012-02-29 22:00:00

+0

@WillGorman對於您的使用案例,[plecong的回答](http://stackoverflow.com/a/9507914/6509)可能比我的更好,更清潔:-) – 2012-03-01 09:17:00