【问题标题】:How does Generic work if generic is Int in Kotlin?如果在 Kotlin 中泛型是 Int,泛型如何工作?
【发布时间】: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&lt;out Int&gt;,但找到的参数是IntArray。我认为 Kotlin 将 IntArrayArray&lt;*&gt; 视为不同的类,但它不应该这样......

我正在使用 Kotlin 1.4.10,根据this 站点,这似乎是最新版本。

我发布这个是为了检查这两个问题是错误还是我做错了什么,因为当我将通用更改为 String 时,所有问题都会被删除。 我在上面的这些示例代码中是否有任何错误?

【问题讨论】:

  • 似乎被覆盖的方法看起来像int... data,而JVM上的接口一个Integer... data,一个有趣的问题!
  • 一种解决方法可能是让参数为空——Int? 而不是Int——这应该会强制它使用通用的Array。丑,当然,但似乎没有一个整洁的解决方案。 (一个更丑陋的极端案例是由于 JVM 中关于数组和泛型做出的相互冲突的决定……)
  • vararg 的使用似乎是关键。只需将其更改为 hello(data: Int) 即可。看起来你发现了一个限制/错误。

标签: kotlin generics


【解决方案1】:

已知问题:https://youtrack.jetbrains.com/issue/KT-9495

作为一种解决方法,您可以使用加框的java.lang.Integer

class Hello : Test<Integer>() {
    override fun hello(vararg data: Integer) {
        super.hello(*data)
        println("Override function")
    }
}

【讨论】:

  • 创建时间:5 年前。状态:待讨论。看起来解决这个问题对 Kotlin 团队来说并不是一个高优先级。
  • 有趣的是,如果我们使用Integer,IDEA 会警告我们不要使用Integer,而我们不能使用Int。我希望 Kotlin 团队可以在不久的将来解决这个问题,因为我认为 Int 将在用户中被非常频繁地用作通用。我会接受这个答案作为解决方案,因为事实证明这个问题无法正确解决,并且它是已知问题...... 5 年
猜你喜欢
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 1970-01-01
相关资源
最近更新 更多