函数toArray
应将类型清除列表转换为T
Array<String>
。
inline fun <reified T> toArray(list: List<*>): T {
return list.toTypedArray() as T
}
toArray<Array<String>>(listOf("a", "b", "c")) // should be arrayOf("a", "b", "c")
但是,toArray
会抛出此错误。
java.lang.ClassCastException:[Ljava.lang.Object;无法转换为[Ljava.lang.String;
你有什么想法吗?
答案 0 :(得分:39)
问题在于,您实际上是尝试使用Java来Object[]
转换为String[]
,或者根据Kotlin将Array<Any>
转换为Array<String>
,但这是不同的对象
所以,这句话:
list.toTypedArray()
返回Array<Any?>
,然后您尝试将其投放到Array<String>
并获取ClassCastException
。
我建议传递类型参数本身,并投射List
:
inline fun <reified T> toArray(list: List<*>): Array<T> {
return (list as List<T>).toTypedArray()
}
toArray<String>(listOf("1", "2"))
答案 1 :(得分:3)
我建议您强烈要求将List<*>
转换为类型化数组(例如Array<String>
)而不是类型化列表(例如List<String>
)。
后者可以在Kotlin中很好地完成:
list.map { it as String }
我建议您阅读Difference between List and Array types in Kotlin和Java Practices -> Prefer Collections over older classes。
如果您仍然觉得需要使用数组,那么我建议您创建一个类似于Kotlin各种“地图”功能的“地图”功能:
inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R> {
return when (this) {
is RandomAccess -> Array(size) { index -> transform(this[index]) }
else -> with(iterator()) { Array(size) { transform(next()) } }
}
}
然后,您可以有效地将List<*>
转换为类型化数组:
list.mapToTypedArray { it as String }
答案 2 :(得分:0)
出于某种原因,当我尝试这样做时,我得到了无效的参数编号异常:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = argumentTypeMirrors.toTypedArray()
我最终这样做了:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = Array(argumentTypeMirrors.size) {
argumentTypeMirrors[it]
}
然后,我可以使用array
销毁我的*array
,并将其作为varargs
参数传递。