首页 > 解决方案 > 如何将 TBase 列表转换为 TChild 列表,其中 TChild : TBase using KClass?

问题描述

我有一个列表TBase,我知道是TChild, where的列表TChild : TBase。如果我只有,是否可以KClass<TChild>投到?List<TBase>List<TChild>

fun <TChild : BaseType> castList(list: List<BaseType>, clazz: KClass<TChild>): List<TChild> {
    // is this possible?
}

我知道如果List不参与,我可以将一个实例TBase转换为TChild

clazz.cast(item)

我正在尝试做的事情可能吗?寻求避免具体化的解决方案。

标签: javakotlingenericsjvm

解决方案


如果您确实确定它TChild仅包含对象并且在强制转换后不会向其添加任何其他对象(List只读,不是不可变的),那么您可以像这样进行未经检查的强制转换:

fun <TChild : BaseType> castList(list: List<BaseType>, clazz: KClass<TChild>): List<TChild> {
    @Suppress("UNCHECKED_CAST")
    return list as List<TChild>
}

如果您更喜欢在投射时实际检查项目类型,请执行以下操作:

fun <TChild : BaseType> castList(list: List<BaseType>, clazz: KClass<TChild>): List<TChild> {
    return list.map { clazz.cast(it) }
}

请注意,第二个解决方案会创建列表的副本,因此这不完全是强制转换。如果您打算在转换后修改原始列表,这一点很重要,因为正如我所说,List它不是不可变的,而是只读的。


推荐阅读