2017-03-09 74 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