Kotlin language obtiene class en time de ejecución
Digamos que tenemos lo siguiente:
val person = "Bill"
¿Alguien podría explicar la diferencia entre estos dos?
- Kotlin: ¿Cómo puedo usar la reflexión en los packages?
- Configurar la reflexión de kotlin, class.java no funciona
- Llamadas a function de logging usando reflexión en kotlin
- ¿Cómo get la reference de class de KParameter en kotlin?
- ¿Cómo cambiar un campo de miembro con la reflexión de Kotlin?
val kClass1 = person.javaClass.kotlin
vs
val kClass2 = person::class
¿Cuándo debería llamar a uno en lugar de a otro?
Se apreciará cualquier ejemplo de código fuente.
- ¿Cómo puedo get una reference a un object Kotlin por su nombre?
- instancia :: class.java vs. instance.javaClass
- ¿El comstackdor de Kotlin siempre conserva los nombres de los parameters en bytecode?
- ¿Cómo obtengo el valor de una propiedad con reflection?
- ¿Cómo get una class de time de ejecución de una variable en Kotlin?
- El operador de Kotlin Reflection obtiene la implementación
- Kotlin obtiene la anotación de campo siempre vacía
- Kotlin comtesting si la function requiere parámetro de instancia
La razón principal por la que hay dos maneras de lograr lo mismo, es decir, get la class Kotlin de un object, es porque antes de Kotlin 1.1, el literal ::class
no admitía la expresión en su lado izquierdo. Entonces, si estás usando Kotlin 1.0, tu única opción es .javaClass.kotlin
, de lo contrario estás bien con cualquiera de ellos. Esta es la razón por la cual "Kotlin en Acción" usa la syntax de .javaClass.kotlin
: fue escrita antes del lanzamiento de Kotlin 1.1.
También hay una pequeña diferencia en los types de estas expresiones. Por ejemplo, en el siguiente código
interface T fun f1(x: T) = x::class fun f2(x: T) = x.javaClass.kotlin
El tipo de f1
es KClass<out T>
, pero el tipo de f2
es KClass<T>
. Esto es realmente un descuido en la statement javaClass
: KClass<out T>
es más correcto en este caso, porque la class x
no es necesariamente T
, sino que también puede ser una subclass de T
De lo contrario, estas dos expresiones ( x.javaClass.kotlin
y x::class
) son completamente equivalentes en términos de bytecode producido y performance en time de ejecución. Prefiero x::class
porque es más corta y lee mejor.
person.javaClass.kotlin
crea un nuevo object de reference de class Kotlin de la class Java. Entonces tiene sentido solo si solo tienes un object de class java.
Entonces debería usar person::class
porque en este caso solo obtiene la class Kotlin directamente sin asignación de objects adicionales
Nadie puede replace a otro. Ambos tienen motivos para existir.
SI obtiene un KClass
de una variable que no puede ser null
entonces prefiere usar foo::class
ya que javaClass.kotlin
crea una nueva instancia cada vez, por ejemplo:
assert(foo::class === foo::class); assert(foo.javaClass.kotlin !== foo.javaClass.kotlin);
SI obtienes un KClass
de una variable que se puede anular, entonces prefieres usarlo como se KClass
a continuación:
val value:Int? = 1; val type = value?.javaClass?.kotlin;
SI obtienes una Class
Java de kotlin, quieres transformarte en KClass
luego usar Class.kotlin
por ejemplo:
val javaClass:Class<Integer> = ...; val kotlinClass:KClass<Integer> = javaClass.kotlin;