¿Cómo get una class de param genérica en Kotlin?

Necesito poder decir el tipo genérico de la colección de kotlin en time de ejecución. ¿Cómo puedo hacerlo?

val list1 = listOf("my", "list") val list2 = listOf(1, 2, 3) val list3 = listOf<Double>() /* ... */ when(list.genericType()) { is String -> handleString(list) is Int -> handleInt(list) is Double -> handleDouble(list) } 

Los generics de Kotlin comparten la característica de Java de ser borrados en time de compilation, por lo que, en time de ejecución, esas lists ya no llevan la información necesaria para hacer lo que estás pidiendo. La exception a esto es si escribe una function en línea, utilizando types reificados. Por ejemplo, esto funcionaría:

 inline fun <reified T> handleList(l: List<T>) { when (T::class) { Int::class -> handleInt(l) Double::class -> handleDouble(l) String::class -> handleString(l) } } fun main() { handleList(mutableListOf(1,2,3)) } 

Sin embargo, las funciones en línea se expanden en cada sitio de llamadas y confunden los rastros de stack, por lo que debe usarlas con moderación.

Dependiendo de lo que intentes lograr, hay algunas alternativas. Puede lograr algo similar a nivel de elementos con classs selladas:

 sealed class ElementType { class DoubleElement(val x: Double) : ElementType() class StringElement(val s: String) : ElementType() class IntElement(val i: Int) : ElementType() } fun handleList(l: List<ElementType>) { l.forEach { when (it) { is ElementType.DoubleElement -> handleDouble(it.x) is ElementType.StringElement -> handleString(it.s) is ElementType.IntElement -> handleInt(it.i) } } } 

Puede usar funciones en inline con parameters de types reified para hacer eso:

 inline fun <reified T : Any> classOfList(list: List<T>) = T::class 

(demostración ejecutable, que incluye cómo verificar el tipo en una statement when )

Esta solución se limita a los casos en que el argumento de tipo real para T se conoce en time de compilation, porque las funciones en inline se transforman en time de compilation y el comstackdor sustituye sus parameters de tipo reified con el tipo real en cada sitio de llamada.

En JVM, los arguments de tipo de las classs genéricas se borran en el time de ejecución, y básicamente no hay forma de recuperarlos de una List<T> arbitraria (por ejemplo, una list pasada a una function no en línea como List<T>T es no se conoce en time de compilation para cada llamada y se borra en time de ejecución)

Si necesita más control sobre el parámetro tipo reificado dentro de la function, puede que le resulte útil esta sección de preguntas y respuestas .

  • java static final en kotlin: el inicializador de Const 'val' debe ser un valor constante
  • ¿Cómo almacenar datos json cuando uso Android Studio 3.0?
  • El plugin de comstackdor abierto de Kotlin no funciona
  • Método abstracto de Kotlin con cuerpo
  • Ejecutar service en segundo plano
  • ¿Existe alguna forma conveniente de crear classs de datos plotbles en Android con Kotlin?
  • ¿Cómo propagar arguments pnetworkingeterminados entre funciones en Kotlin?
  • Generalizar método con arguments anulables y tipo de retorno
  • Android: la barra de herramientas no se muestra
  • Android / Kotlin Crash en Start 4.1.2 - ExceptionInInitializerError
  • kotlin oyentes de clics múltiples en los botones