Kotlin编译器的类型推断不能选择调用哪个方法(带有泛型类型的歧义)

所以,我有一些这些签名的Java方法(为简单起见,删除了注释和代码体):

public class JavaClass { public static <E extends CharSequence> E join(E... array) { ... } public static <E extends CharSequence> E join(CharSequence separator, E... array) { ... } } 

我在Kotlin中有一些代码,它调用了'join'方法:

 class KtClass { fun test(vararg array: String) { JavaClass.join(*array) } } 

到现在为止还挺好; 它会传播可变参数并称之为方法签名。 好的!

例如,如果我想用“分隔符”参数来调用后一个方法签名,就会出现问题:

 class KtClass { fun test(vararg array: String) { JavaClass.join("<br>", *array) } } 

这段代码不会编译。 编译器无法决定调用哪个方法。 错误:

错误:(5,13)Kotlin:不能完成类型推断之间的以下候选人之间:public open fun join(vararg array:String!):String! 在JavaClass public open fun join中定义(分隔符:CharSequence!,可变长度数组:String!):String! 在JavaClass中定义

我甚至不能说出这些论点,因为Kotlin没有让参数命名为非Kotlin函数。

编辑:用Java方法头中的普通字符串引用替换E泛型类型参数,它的工作! 所以我想这是与泛型类型或类似的类型推断不兼容?



我非常确定这是一个扩散运算符 (*)。 但是,如果我不使用它,我不能将varargs参数array传递给join函数。

我怎样才能解决这个问题,而不必触摸Java代码?

是的,我知道有Array.joinToString扩展函数,但是这只会解决这个特殊情况。 我需要知道一个通​​用的解决方案。

我不认为这是Kotlin特定的。 问题是泛型参数ECharSequence类型的,所以你的调用变成类似于E == CharSequence join("separator", "word1", "word2") ,这实际上是自第一个参数以来不明确的。与其他参数的类型相同。

看起来你需要在Java中创建一个辅助类来弥补互操作问题。 例如:

 public class JavaClassInterop { public static <E extends CharSequence> E joinSeparatedBy(CharSequence separator, E... array) { return JavaClass.join(separator, array); } } 

那么你可以调用两个:

 import JavaClass.join import JavaClassInterop.joinSeparatedBy fun main(args: Array<String>) { join(*args) joinSeparatedBy("<br>", *args) } 
Interesting Posts