関数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;にキャストできません。
あなたはなにか考えはありますか?
ここでの問題は、実際にObject[]
をString[]
にJavaでキャストしようとしていること、または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"))
型付きリスト(例:List<*>
)ではなく、Array<String>
を型付き配列(例:List<String>
)に変換する必要性に挑戦することをお勧めします。
後者はKotlinで非常にうまく行うことができます。
list.map { it as String }
Kotlinのリスト型と配列型の違い および Javaプラクティス->古いクラスよりもコレクションを優先 を読むことをお勧めします。
それでも配列を操作する必要があると感じる場合は、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 }
何らかの理由で、これを実行しようとしたときに無効な引数番号の例外が発生していました:
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
を破棄することができました。