Kotlin语言在运行时获得类

假设我们有以下几点:

val person = "Bill" 

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

 val kClass1 = person.javaClass.kotlin 

VS

 val kClass2 = person::class 

当我应该叫那个而不是另一个?

任何源代码示例将不胜感激。

有两种方法来达到同样的目的,即得到一个对象的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因为它更短,读得更好。

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

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

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

如果你从一个不能为null的变量中获得一个KClass ,那么你更喜欢使用foo::class因为javaClass.kotlin创建一个新的实例,例如:

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

如果你从一个可为空的变量中获得一个KClass ,那么你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;