Kotlin语言在运行时获取类

时间:2017-06-15 07:11:38

标签: reflection kotlin

假设我们有以下内容:

val person = "Bill"

有人可以解释这两者之间的区别:

val kClass1 = person.javaClass.kotlin    

VS

val kClass2 = person::class

什么时候应该打电话给那个而不是另一个?

任何源代码示例都将受到赞赏。

3 个答案:

答案 0 :(得分:7)

有两种方法可以实现同样的事情,即得到一个对象的Kotlin类,是因为在Kotlin 1.1之前,::class文字不支持左侧的表达式。因此,如果你正在使用Kotlin 1.0,那么你唯一的选择就是.javaClass.kotlin,否则你对其中任何一个都没问题。这就是" Kotlin in Action"使用.javaClass.kotlin语法:它是在Kotlin 1.1发布之前编写的。

这些表达的类型也存在细微差别。例如,在以下代码中

interface T

fun f1(x: T) = x::class
fun f2(x: T) = x.javaClass.kotlin

f1的类型为KClass<out T>,但f2的类型为KClass<T>。这实际上是javaClass声明中的疏忽:KClass<out T>在这种情况下更正确,因为x的类不一定是T,但也可以是T的子类。

否则这两个表达式(x.javaClass.kotlinx::class)在生成的字节码和运行时性能方面完全相同。我更喜欢x::class,因为它更短,读起来更好。

答案 1 :(得分:0)

person.javaClass.kotlin从Java类创建新的Kotlin类引用对象。所以只有你只有java类对象才有意义。

所以你应该使用person::class,因为在这种情况下你只需直接获得Kotlin类而无需额外的对象分配

答案 2 :(得分:0)

没有人可以取代另一个,他们都有理由存在。

如果,您从KClass的变量中获得null,那么您更喜欢使用foo::class,因为javaClass.kotlin创建了每次都有新实例,例如:

assert(foo::class === foo::class); 
assert(foo.javaClass.kotlin !== foo.javaClass.kotlin); 

IF 您从可以为空的变量中获得KClass,然后更喜欢使用如下所示:

val value:Int? = 1;

val type = value?.javaClass?.kotlin;

如果你从kotlin获得了一个java Class,你希望转换为KClass,然后使用Class.kotlin,例如:

val javaClass:Class<Integer> = ...;
val kotlinClass:KClass<Integer> = javaClass.kotlin;