我尝试从Kotlin调用一个自定义Java集合,它以这种方式实现了一个add(long value)
方法:
public class SomeSet<T> {
public void add(int value) { }
public void add(long value) { }
public void add(T value) { }
}
在Java中,我们可以调用重载方法而不会有任何问题:
SomeSet<Long> set = new SomeSet<Long>();
set.add(1);
set.add(1L);
但在Kotlin中,这似乎是不可能的:
val set = SomeSet<Long>()
set.add(1 as Int)
set.add(1L) // ⚡ Overload resolution ambiguity
set.add(1L as Long) // ⚡ Overload resolution ambiguity
完整编译错误:
Overload resolution ambiguity. All these functions match.
public open fun add(value: Long): Unit defined in de.itscope.platform.producttracking.test.SomeSet
public open fun add(value: Long!): Unit defined in de.itscope.platform.producttracking.test.SomeSe
我已经检查了建议,对于一个很可能的问题:
Kotlin:当Java库同时具有原始类型和装箱类型的重载时,我该怎么办?
但这在这里没有帮助,因为这个泛型重载。
这不是学术示例。这是com.google.zetasketch.HyperLogLogPlusPlus
类的实现方式。来自ZetaSketch库的HyperLogLog++实现。
2条答案
按热度按时间eh57zj3b1#
在Java中,我们可以调用重载方法而不会有任何问题:
但这只是因为
Long
在Java和Kotlin中有不同的含义。在Java中它是java.lang.Long
,而SomeSet<Long>
有方法add(long value)
和add(java.lang.Long value)
。没有冲突!而Kotlin的kotlin.Long
更接近Java的long
,因此SomeSet<kotlin.Long>
有两个方法接受kotlin.Long
。所以你的工作Java示例的等效内容是Kotlin会警告你通常不应该在Kotlin中使用
java.lang.Long
,但在这种情况下,我认为这是正确的。作为替代方案,您不一定需要更改
set
变量本身的类型,只需在想要调用该方法时对其进行强制转换:Playground(我还没有用Java中实际定义的
SomeSet
进行测试,但我不希望Kotlin等价物的行为有所不同)。fdx2calv2#
我发现调用
add
函数的唯一方法是,将Any
设置为泛型类型: