【问题标题】:why List<String> can cast to List<Int> in Kotlin?为什么 List<String> 可以在 Kotlin 中转换为 List<Int>?
【发布时间】:2022-01-28 17:27:15
【问题描述】:

为什么下面的代码可以运行?

fun main(args: Array<String>) {


    val somePair: Pair<Any?, Any?> = "items" to listOf("1","2a")
    var W=somePair.second as List<Int>
    println(W)
}

输出:[1, 2a]

“2a”不是Int,但是W的类型是List,为什么不抛出异常?

【问题讨论】:

  • 另请注意,您会收到来自编译器的警告,即未检查强制转换 (as List&lt;Int&gt;)。
  • 强制转换是合法的,因为你将Any? 强制转换为List&lt;Int&gt;,所以这里也不例外,编译器不会分析列表的实际内容。 println(W) 隐式调用 W.toString()(实际上是 List.toString(),此处删除了 Int 类型),因此也不会出现异常。如果您打印列表的第二个元素 (println(W[1])) 将引发异常,因为“2a”无法转换为 Int

标签: kotlin


【解决方案1】:

编译您的代码会给出以下警告:

Unchecked cast: Any? to List<Int>

这字面意思是强制转换不会在所有情况下抛出异常。如果您选择忽略此警告,则应为这种行为的发生做好准备。

现在关于为什么这实际上运行良好,请记住泛型类型在运行时被删除。这意味着List&lt;String&gt;List&lt;Int&gt; 在运行时实际上只是一个原始List,有关元素类型的信息会丢失。

泛型的主要作用是在编译代码时提供帮助:编译器会阻止您将错误类型的元素添加到列表中,并且当您从列表中读取元素时,它会通过给您一个值来帮助您正确的类型(不需要强制转换)。

但是,演员表在运行时运行。他们根据给定类型检查对象的运行时类型。您转换为的类型 List&lt;Int&gt; 是泛型类型,编译器会警告您,因为在运行时它只会看到原始接口 List

更具体地说,somePair.second as List&lt;Int&gt;somePair.second 的运行时类型(此处为ArrayList)与原始List 接口进行比较——这是匹配的,所以也不例外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    相关资源
    最近更新 更多