2017-03-09 39 views
4

當我嘗試使用包含帶有函數參數的重載方法的代碼時,我得到了Ambiguous error帶功能參數的Groovy閉包和重載方法

我寫了一個小片段,顯示一個模糊的行爲:

import java.util.function.BiConsumer 
import java.util.function.Consumer 

class Test { 

    static void main(String... args) { 
     execute({ x -> println("Consumer") }) 
     execute({ x, y -> println("BiConsumer") }) 
    } 

    static void execute(Consumer<Integer> c) { 
     c.accept(100) 
    } 

    static void execute(BiConsumer<Integer, Integer> c) { 
     c.accept(1, 2) 
    } 
} 

輸出(2.4.9常規):

Exception in thread "main" groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method Test#execute. 
Cannot resolve which method to invoke for [class Test$_main_closure1] due to overlapping prototypes between: 
    [interface java.util.function.BiConsumer] 
    [interface java.util.function.Consumer] 
    at groovy.lang.MetaClassImpl.chooseMostSpecificParams(MetaClassImpl.java:3268) 
    at groovy.lang.MetaClassImpl.chooseMethodInternal(MetaClassImpl.java:3221) 
    at groovy.lang.MetaClassImpl.chooseMethod(MetaClassImpl.java:3164) 
    at groovy.lang.MetaClassImpl.pickStaticMethod(MetaClassImpl.java:1516) 
    at groovy.lang.MetaClassImpl.retrieveStaticMethod(MetaClassImpl.java:1412) 
    at org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.chooseMeta(Selector.java:553) 
    at org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.setCallSiteTarget(Selector.java:954) 
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:228) 
    at Test.main(Test.groovy:7) 

但它與Java-lambda表達式的作品,我不明白在這種情況下如何使用groovy-closure。

回答

2

你需要把as XXX你關閉後得到的運行時,你想要去的線索

execute({ x -> println("Consumer") } as Consumer) 
    execute({ x, y -> println("BiConsumer") } as BiConsumer) 

應該這樣做

+0

謝謝,它有助於這種情況。但例如如果一些java庫通過添加新的重載方法改變了自己的api,它可能會打破常規代碼? –

+0

您可以使用'@ CompileStatic'在編譯時捕獲它們 –

0

也許使用Closure

execute(Closure <Integer> c) { 
    c (10) 
} 

execute (Closure <Integer, Integer> c) { 
    c (10, 30) 
} 
+2

你可以閉包',閉包只接受一個泛型參數,閉包的返回類型 –

+0

解決方案不起作用。 – Rao