【发布时间】:2021-02-13 12:45:56
【问题描述】:
我试图了解如何从代码中抛出 ClassCastException,据我所知,被转换为的类型已被删除。
示例
class Foo<T : Any>(val key: String, val value: T) {
override fun toString() = "$key: $value"
}
fun <T : Foo<*>> findByKey(items: Iterable<Foo<*>>, key: String): List<T> {
return items.filter { it.key == key } as List<T>
}
fun main() {
val items = listOf(
Foo("a", "abc"),
Foo("a", 12345),
Foo("a", false)
)
val filtered = findByKey<Foo<String>>(items, "a")
println(filtered)
val values = filtered.map { it.value }
println(values)
}
输出
[a: abc, b: 12345, c: 假]
线程“main”java.lang.ClassCastException 中的异常:java.lang.Integer 无法转换为 java.lang.String
这里有几个疼的拇指:
- 在
findByKey中键入T不是reified,因此被删除。 -
findByKey接受Iterable<Foo<*>而不是Iterable<T>(故意)。 -
List<T>存在未经检查的强制转换。
我觉得有趣的是:
- 调用
findByKey<Foo<String>>(items, "a")不会抛出ClassCastException。 - 在 JVM 中,我希望此调用为
findByKey(items, "a"),因为<Foo<String>>已被删除。 - 调用
filtered.map { it.value }会抛出ClassCastException。
我不是在寻找如何让这段代码正常工作的解决方案;我已经知道了。相反,我很想知道为什么调用map 会为我认为会被删除的类型抛出ClassCastException?
【问题讨论】:
标签: kotlin