【发布时间】:2020-11-14 12:13:15
【问题描述】:
我尝试制作抽象类进行测试,因为我发现使用泛型的奇怪问题
abstract class Test<T> {
open fun hello(vararg data: T) {
print("Default function")
}
}
这个非常简单的抽象类有一个带有 vararg 关键字的打开方法。可以通过制作另一个扩展 Test 类的类来重现问题。
class Hello : Test<Int>() {
//Problem 1
override fun hello(vararg data: Int) {
super.hello(*data) //Problem 2
println("Override function")
}
}
关于第一个问题,Kotlin 说方法不会覆盖任何东西,即使这个方法肯定会覆盖某些东西。奇怪的是,这个错误是随机发生的,所以我不知道重现这个错误的确切方法
当我添加一些代码(比如非常简单的代码,例如println() 等)时,这个错误被消除了,但是当你编译时,它再次导致同样的错误。
关于第二个问题,super.hello(*data) 导致问题,因为这需要Array<out Int>,但找到的参数是IntArray。我认为 Kotlin 将 IntArray 和 Array<*> 视为不同的类,但它不应该这样......
我正在使用 Kotlin 1.4.10,根据this 站点,这似乎是最新版本。
我发布这个是为了检查这两个问题是错误还是我做错了什么,因为当我将通用更改为 String 时,所有问题都会被删除。
我在上面的这些示例代码中是否有任何错误?
【问题讨论】:
-
似乎被覆盖的方法看起来像
int... data,而JVM上的接口一个Integer... data,一个有趣的问题! -
一种解决方法可能是让参数为空——
Int?而不是Int——这应该会强制它使用通用的Array。丑,当然,但似乎没有一个整洁的解决方案。 (一个更丑陋的极端案例是由于 JVM 中关于数组和泛型做出的相互冲突的决定……) -
vararg的使用似乎是关键。只需将其更改为hello(data: Int)即可。看起来你发现了一个限制/错误。