【问题标题】:Unchecked cast of generic class type IDE warning通用类类型 IDE 警告的未经检查的强制转换
【发布时间】:2018-10-10 03:01:12
【问题描述】:

为简单起见,我有这两个类:

abstract class ClassA<T> where T : ClassA<T> {
    fun fooA(): T {
        //Do stuff
        return this as T //<-- Cast warning happens here
    }
}

open class ClassB : ClassA<ClassB>() {
    fun fooB(): ClassB {
        //Do stuff
        return this
    }
}

我在 fooA 函数中标记的那一行被 IntelliJ 标记为以下警告: "Unchecked cast: ClassA&lt;T&gt; to T"。除非我遗漏了什么,否则我设置类的方式应该使函数 fooA 中的返回类型不可能不是 ClassA 的子级,这意味着强制转换检查将是多余的。或者至少我看不到 fooA 可以尝试将 ClassA 强制转换为不是它的子对象的方式。我是否遗漏了什么,或者我可以取消警告?

【问题讨论】:

  • 好问题。这显示了 Java(以及 Kotlin)类型系统的弱点。 typeclass 解决了这个问题。

标签: generics inheritance casting kotlin warnings


【解决方案1】:

警告是正确的。因为你可能会用这样的邪恶参数填充泛型参数:

class ClassC : ClassA<ClassB>()

现在您只需在ClassC 上调用fooA 即可生成ClassCastException

fun main(args: Array<String>) {
    val fooA = ClassC().fooA()
}

这就是fooA 不安全的原因。

在编译时无法检测到此类错误,这就是出现警告的原因。

当然,您可以手动确保您的代码不会以错误的方式填充泛型参数并抑制警告。

【讨论】:

  • 啊,我现在看到了这个问题。不过,您不能进行类型检查泛型(并不是说它会帮助解决这个问题)。手动确保我不会使那些泛型类型错误成为合理的路径吗?或者您知道是否有解决此问题的已知解决方案?
  • 这显示了 Java(以及 Kotlin)类型系统的弱点。 typeclass(一种语言特性,Haskell/Scala 有这个)解决了这个问题。看看my old question,它正在寻找类似的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
相关资源
最近更新 更多