Solo se pueden usar parámetros de tipo cosificados con funciones en línea. Entonces, si quiero un parámetro de este tipo para una clase, necesito un truco como este:
class Foo<T : Any>(private val clazz: KClass<T>) { companion object { inline fun <reified T: Any> create() = Foo(T::class) } } Entonces puedo crear instancias de Foo como esta:
val foo = Foo.create<Bar>() Dentro de Foo , tengo acceso a clazz pero mi pregunta es : ¿puedo usar clazz cuando necesito llamar a métodos que requieren un parámetro de tipo reificado ?
Por ejemplo, dentro de Foo me gustaría agregar un método como este:
fun print(list: List<Alpha>) { list.filterIsInstance<T>().forEach { print(it) } } Pero por lo que puedo ver, no hay forma de pasar de clazz a algo que pueda usar como parámetro de tipo aquí.
Y sí, sé que hay una forma de filterIsInstance que toma una Class , así que puedo hacer:
list.filterIsInstance(clazz.java).forEach { print(it) }Sin embargo, muchas bibliotecas contienen métodos en los que no se proporcionan ambas formas (parámetro de clase explícito y parámetro de tipo cosificado).
Por ejemplo, Jackson Kotlin Extensions.kt . En realidad, este no es un gran ejemplo, ya que los equivalentes no cosificados son todos de una sola línea, pero no siempre es así; luego termina desempaquetando la implementación del método de parámetro de tipo cosificado en su código.
no, porque esas funciones están inline , están en línea en tiempo de compilación y una Clase o KClass está usando la reflexión en tiempo de ejecución
hay algunos trucos que puede hacer... como con la clase complementaria, pero eso no necesita KClass<T> en absoluto... cualquier otra cosa que proporcione un argumento genérico de T funcionaría igual de bien para la información de tipo reified
PD: la reflexión tampoco puede ayudarlo de manera confiable porque las funciones en línea realmente no existen en tiempo de ejecución, como se explica por su modificador inline
A menos que me esté perdiendo algo, todo lo que puede hacer con T en una función con reified T se puede traducir a un uso de KClass : por ejemplo x is T se convierte en clazz.isInstance(x) , x as T se convierte en clazz.cast(x) , las llamadas de otras funciones con parámetros de tipo cosificado se traducen recursivamente, etc. Dado que la función debe estar en línea, todas las API que utiliza están visibles en el sitio de la llamada para que la traducción se pueda realizar allí.
Pero no hay una forma automática de hacer esta traducción, que yo sepa.