You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Kotlin中Double可转<T: Number>泛型却无法直接转为Int?

问题原因解析

核心是JVM的泛型擦除机制和Kotlin的类型转换时机共同导致的差异,具体如下:

  • 泛型擦除弱化了强转检查
    JVM的泛型采用类型擦除实现,编译阶段会将所有泛型类型参数替换为其上限类型。你定义的<T : Number>编译后会统一替换为Number,因此函数内的sum as T实际编译后是sum as Number。而Double本身就是Number的子类,这个强转完全合法,运行时不会抛出任何异常。此时编译器会给出「未检查转换」的警告,就是在提示你这个强转的合法性无法在编译期验证,风险由开发者自行承担。
  • 调用处的类型转换被延后甚至不触发
    你的示例中直接将sum(listOf(1,2,3))传入println,而println接收的参数类型是Any,编译器不需要将返回的Number强转为推断出的Int类型,因此不会触发实际的类型检查。如果修改代码为显式用Int接收返回值:
fun main() {
    val res: Int = sum(listOf(1,2,3))
    println(res)
}

运行时就会抛出和直接强转完全一致的ClassCastException: java.lang.Double cannot be cast to java.lang.Integer。

  • 直接强转的类型检查是即时的
    你写的d as Int是明确要求将Double实例转换为Int类型,二者不存在继承关系,JVM运行时会直接检查类型兼容性,因此会立刻抛出异常。

内容的提问来源于stack exchange,提问作者Markus Weninger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:24:06