Cómo get la class de parámetro genérico en Kotlin

Snapshot.getValue snapshot.getValue() Firebase espera ser llamado de la siguiente manera:

 snapshot?.getValue(Person::class.java) 

Sin embargo, me gustaría sustituir a Person con un parámetro genérico que se pasa a la class a través de la statement de class, es decir,

 DataQuery<T : IModel> 

y use ese parámetro genérico para hacer algo como esto:

 snapshot?.getValue(T::class.java) 

pero cuando bash recibir un error que indica que

solo las classs se pueden usar en el lado izquierdo de un literal de class

¿Es posible proporcionar una restricción de class en el parámetro genérico como en C # o hay alguna otra syntax que pueda usar para get la información de tipo para el param genérico?

Lo que necesita es un modificador reificado para su param genérico, puede leerlo aquí. https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters Entonces, si haces algo como eso:

 inline fun <reified T : Any>T.logTag() = T::class.java.simpleName 

obtendrá el nombre de la class de llamada real, no "Objeto".

Para una class con parámetro genérico T, no puede hacer esto porque no tiene información de tipo para T ya que la JVM borra la información de tipo. Por lo tanto, un código como este no puede funcionar:

 class Storage<T: Any> { val snapshot: Snapshot? = ... fun retrieveSomething(): T? { return snapshot?.getValue(T::class.java) // ERROR "only classes can be used..." } } 

Pero puede hacer que esto funcione si el tipo de T se reifica y se usa dentro de una function en línea:

 class Storage { val snapshot: Snapshot? = ... inline fun <reified T: Any> retrieveSomething(): T? { return snapshot?.getValue(T::class.java) } } 

Tenga en count que la function en línea, si es pública, solo puede acceder a miembros públicos de la class. Pero puede tener dos variantes de la function, una que recibe un parámetro de class que no está en línea y accede a elementos internos privados, y otra function auxiliar en línea que realiza la reificación a partir del parámetro de tipo inferido:

 class Storage { private val snapshot: Snapshot? = ... fun <T: Any> retrieveSomething(ofClass: Class<T>): T? { return snapshot?.getValue(ofClass) } inline fun <reified T: Any> retrieveSomething(): T? { return retrieveSomething(T::class.java) } } 

También puede usar KClass lugar de Class para que los llamadores que solo son Kotlin puedan usar MyClass::class lugar de MyClass::class.java

Si desea que la class coopere con el método en línea de los generics (lo que significa que la class de Storage solo almacena objects de tipo T ):

 class Storage <T: Any> { val snapshot: Snapshot? = ... inline fun <reified R: T> retrieveSomething(): R? { return snapshot?.getValue(R::class.java) } } 

El enlace a types reificados en funciones en línea: https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters

  • Convierte java en kotlin en pasta
  • ¿Cómo escribir lambdas con generics en kotlin?
  • ¿Cómo creo una variable de function con una cantidad variable de arguments?
  • Cómo alternar la visibilidad de FAB con otro FAB
  • ¿Cómo puedo hacer que cada punto final de descanso lea una cookie y use ese valor en okhttp Interceptor?
  • Kotlin + Dagger - Inyectar map para ViewModel fábrica
  • ¿Es posible restringir el tipo de una Lista a una implementación de una interfaz en Kotlin?
  • Combustible TimeOut Connection
  • ¿Por qué sumBy (selector) no devuelve Long?
  • ¿Hay alguna forma mejor de escribir invocaciones de CompletableFutrue.XXXasync () en kotlin?
  • Se llama a Kotlin OnTouchListener pero no anula el funcionamientoHaga clic en