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.kotlin
和x::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;